2012-02-04 5 views
8

Sé que no puedo pasar parámetros al constructor Activity en Android, pero me gustaría entender por qué.Por qué no puedo pasar los parámetros a Android Activity Constructor

Lo que he tratado de hacer es:

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

he definido la clase de la siguiente manera:

public class CalorieSelectorActivity extends Activity { 

public CalorieSelectorActivity(String name) { 
    super(); 

} 

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

} 
} 

y funciona perfectamente cuando quito los parámetros del constructor. Finalmente lo hice usando intent.putExtra, pero tengo mucha curiosidad por saber por qué no se puede hacer pasando los parámetros al constructor.

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

Por cierto, ¿puedes poner el contenido del error en alguna parte que podamos verificar? pastebin o una esencia – DallaRosa

+1

No tendría ni idea de cómo hacerlo. ¿Puedo publicar el LogCat? @DallaRosa –

+0

Actualicé mi respuesta para reflejar la información que no había visto la primera vez que leí su pregunta. – DallaRosa

Respuesta

17

referencia a su código:

CalorieSelectorActivity csa = new CalorieSelectorActivity(userName); 

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

startActivity(i); 

Incluso si se crea un objeto de su actividad, lo que está "de paso" en el objeto intención no es la activity object pero sólo el class of your activity. En startActivity(), el marco Android intentará crear instancias de un objeto de su actividad. Y llama al constructor predeterminado (sin parámetros) cuando lo hace. Falla cuando su clase no tiene un constructor sin parámetros.

Por supuesto, ha encontrado la solución correcta, pasa los parámetros como parte del objeto Intención.

+0

Al principio estaba tratando de hacer eso para poder pasar un objeto personalizado a la clase de actividad porque necesitaba usarlo allí, pero cuando eso falló, intenté con una cadena simple. Como se muestra en mi pregunta. Luego me entregué y lo pasé a través del intento. @ Sameer –

+0

¿Y el hecho de que mi declaración de clase tiene un argumento, y el objeto "csa" que defino está basado en esa clase? ¿No debería Android tratar de llamar a ese constructor de clase (que finalmente llama al constructor de actividad predeterminado) en lugar de llamar directamente al constructor de actividad predeterminado? Encuentro ese comportamiento muy extraño. @DallaRosa –

+2

No soy realmente un experto en cómo se implementa Android framework. Sin embargo, lo esencial para entender aquí es que el marco utiliza la reflexión para crear una instancia del objeto de su actividad. El objeto que ha creado no está siendo utilizado por el marco. Sugeriría que leas sobre la reflexión de Java. Entonces puede no parecer tan extraño. – Sameer

0

¿Qué error Qué se obtiene cuando se intenta y llama al constructor? Puede pasar valores a nuevas instancias de su actividad llamando a su construcción. Podría o no podría resolver su problema, pero ¿qué sucede si anota su constructor con @override?

Dicho esto, debería utilizar Bundles o los métodos intent.put para poner a su disposición los datos, ya que el sistema puede restaurar esos valores si su actividad está pausada para liberar memoria.

+0

El error que recibo es: –

+0

El error que recibo es: 02-04 03: 39: 58.297: E/AndroidRuntime (713): java.lang.RuntimeException: no se puede instanciar la actividad ComponentInfo {com.manarbushnaq. calorietracker/com.manarbushnaq.calorietracker.CalorieSelectorActivity}: java.lang.InstantiationException: com.manarbushnaq.calorietracker.CalorieSelectorActivity No quise jugar con la constructure, es por eso que estoy llamando al super(). Como dije antes, funciona bien cuando uso el mismo código, excepto sin parámetros.¡Funciona con todas las demás clases, excepto Actividad! –

0

Si realmente necesita para crear un Activity que tiene un constructor (porque, por ejemplo, se está creando una Activity que será lanzado por otra aplicación, como por ejemplo la actividad de edición de un plug-in Tasker), puede hacerlo mediante el uso de una clase derivada, como tan:

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

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

Si necesita para generar el parámetro, sustituya "parameter" con una llamada a una función que devuelve el valor apropiado.

+1

Eso es un "parámetro codificado" .. –

Cuestiones relacionadas