2012-02-04 12 views
8

Wiem, że nie mogę przekazać parametrów do konstruktora działań w systemie Android, ale chciałbym zrozumieć dlaczego.Dlaczego nie mogę przekazać parametrów do konstruktora aktywności Androida?

Co próbowałem zrobić to:

CalorieSelectorActivity csa = new CalorieSelectorActivity(userName); 
       Intent i = new Intent(thisContext, csa.getClass()); 
       startActivity(i); 

I zdefiniowano klasę następująco:

public class CalorieSelectorActivity extends Activity { 

public CalorieSelectorActivity(String name) { 
    super(); 

} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.calorieselector); 

} 
} 

i działa idealnie, kiedy usunąć parametrów z konstruktora. W końcu zrobiłem to za pomocą intent.putExtra, ale jestem bardzo ciekawy, dlaczego nie można tego zrobić, przekazując parametry do konstruktora?

LogCat:

02-04 06:46:52.257: W/dalvikvm(800): threadid=1: thread exiting with uncaught exception (group=0x4001d800) 
02-04 06:46:52.277: E/AndroidRuntime(800): FATAL EXCEPTION: main 
02-04 06:46:52.277: E/AndroidRuntime(800): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.manarbushnaq.calorietracker/com.manarbushnaq.calorietracker.CalorieSelectorActivity}: java.lang.InstantiationException: com.manarbushnaq.calorietracker.CalorieSelectorActivity 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.os.Handler.dispatchMessage(Handler.java:99) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.os.Looper.loop(Looper.java:123) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.ActivityThread.main(ActivityThread.java:4627) 
02-04 06:46:52.277: E/AndroidRuntime(800): at java.lang.reflect.Method.invokeNative(Native Method) 
02-04 06:46:52.277: E/AndroidRuntime(800): at java.lang.reflect.Method.invoke(Method.java:521) 
02-04 06:46:52.277: E/AndroidRuntime(800): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
02-04 06:46:52.277: E/AndroidRuntime(800): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
02-04 06:46:52.277: E/AndroidRuntime(800): at dalvik.system.NativeStart.main(Native Method) 
02-04 06:46:52.277: E/AndroidRuntime(800): Caused by: java.lang.InstantiationException: com.manarbushnaq.calorietracker.CalorieSelectorActivity 
02-04 06:46:52.277: E/AndroidRuntime(800): at java.lang.Class.newInstanceImpl(Native Method) 
02-04 06:46:52.277: E/AndroidRuntime(800): at java.lang.Class.newInstance(Class.java:1429) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.Instrumentation.newActivity(Instrumentation.java:1021) 
02-04 06:46:52.277: E/AndroidRuntime(800): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577) 
02-04 06:46:52.277: E/AndroidRuntime(800): ... 11 more 
+0

btw, czy możesz umieścić zawartość błędu gdzieś, gdzie możemy sprawdzić? pastebin lub istotę – DallaRosa

+1

Nie miałbym pojęcia, jak to zrobić. Czy mogę opublikować LogCat? @DallaRosa –

+0

Zaktualizowałem swoją odpowiedź, aby odzwierciedlić informacje, których nie widziałem, kiedy po raz pierwszy przeczytałem twoje pytanie. – DallaRosa

Odpowiedz

17

Patrz kodzie:

CalorieSelectorActivity csa = new CalorieSelectorActivity(userName); 

Intent i = new Intent(thisContext, csa.getClass()); 

startActivity(i); 

Nawet jeśli utworzyć obiekt swojej działalności, co masz „przejście” w zamiarze obiektu nie jest activity object ale tylko class of your activity. W startActivity() framework systemu Android spróbuje utworzyć instancję obiektu swojej aktywności. I wywołuje domyślny konstruktor (bez parametrów), kiedy to robi. Zawodzi, gdy twoja klasa nie ma konstruktora bez parametrów.

Oczywiście znalazłeś poprawne rozwiązanie, przekazałeś parametry jako część obiektu Intent.

+0

Początkowo próbowałem to zrobić, aby móc przekazać niestandardowy obiekt do klasy aktywności, ponieważ potrzebowałem go tam użyć, ale gdy to się nie udało, wypróbowałem prosty ciąg. Jak pokazuje moje pytanie. Wtedy poddałem się i przekazałem to przez intencję. 'Sameer –

+0

A co z faktem, że moja deklaracja klasy ma argument, a obiekt "csa", który definiuję jest oparty na tej klasie. Czy Android nie powinien próbować wywoływać tego konstruktora klasy (który ostatecznie wywołuje domyślny konstruktor aktywności) zamiast od razu wywoływać domyślny konstruktor aktywności. Uważam to za bardzo dziwne zachowanie. @DallaRosa –

+2

Nie jestem ekspertem od implementacji systemu Android. Najważniejszą rzeczą, którą należy tutaj zrozumieć, jest to, że ramy używają refleksji do utworzenia obiektu swojej aktywności. Obiekt, który utworzyłeś, nie jest używany przez framework. Sugerowałbym, żebyś przeczytał na temat refleksji Java. To może nie wydawać się dziwne. – Sameer

0

Jaki błąd zrobić, gdy spróbujesz i wywołać konstruktora? Możesz przekazywać wartości do nowych instancji swojej aktywności, wywołując jej konstrukcję. To może, ale nie musi, rozwiązać problem, ale co się stanie, jeśli dodasz adnotację do swojego konstruktora przy pomocy @override?

To powiedziawszy, naprawdę powinieneś używać Pakunków lub metod intent.put, aby udostępnić im dane, ponieważ te wartości mogą zostać przywrócone przez system, jeśli Twoja Aktywność zostanie wstrzymana w celu zwolnienia pamięci.

+0

Błąd, który otrzymuję, to: –

+0

Otrzymuję błąd: Otrzymuję błąd: 02-04 03: 39: 58.297: E/AndroidRuntime (713): java.lang.RuntimeException: Nie można utworzyć wystąpienia komponentu ComponentInfo {com.manarbushnaq. calorietracker/com.manarbushnaq.calorietracker.CalorieSelectorActivity}: java.lang.InstantiationException: com.manarbushnaq.calorietracker.CalorieSelectorActivity Nie chciałem bawić się konstrukcją, dlatego nazywam ją super(). Jak już wspomniałem wcześniej, działa to dobrze, gdy używam tego samego kodu, z wyjątkiem bez parametrów.Działa z każdą inną klasą z wyjątkiem działania !!! –

0

Jeśli naprawdę potrzebujesz, aby stworzyć Activity który ma konstruktora (bo, powiedzmy, jesteś stworzenie Activity który zostanie uruchomiony przez innej aplikacji, takich jak aktywność edycji z Tasker wtyczki), można to zrobić za pomocą klasy pochodnej, a więc:

class BaseActivity extends Activity 
{ 
    public BaseActivity(String parameter) 
    { 
     // Do something with parameter 
    } 
} 

class DerivedActivity extends BaseActivity 
{ 
    public DerivedActivity() 
    { 
     super("parameter"); 
    } 
} 

Jeśli trzeba wygenerować parametr wymienić "parameter" z wywołania funkcji, która zwraca odpowiednią wartość.

+1

To jest "zakodowany parametr" .. –

Powiązane problemy