Why I cannot pass parameters to Android Activity C

2020-02-26 06:17发布

问题:

I know that I cannot pass parameters to the Activity constructor in android, but I would like to understand why.

What I tried to do is:

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

I have defined the class as follows:

public class CalorieSelectorActivity extends Activity {

public CalorieSelectorActivity(String name) {
    super();

}

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

}
}

And it works perfectly when I remove the parameters from the constructor. I finally did it using intent.putExtra, but am very curious to know why it cannot be done by passing parameters to the 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

回答1:

Refer to your code:

CalorieSelectorActivity csa = new CalorieSelectorActivity(userName);

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

startActivity(i);

Even if you create an object of your activity, what you are "passing" in the Intent object is not the activity object but just the class of your activity. In startActivity() the Android framework will try to instantiate an object of your activity. And it calls the default constructor (without parameters) when it does that. It fails when your class does not have a constructor without parameters.

Of course, you have found the correct solution, pass the parameters as part of Intent object.



回答2:

I'm surprised that nobody answered the actual question asked! So to answer this Why I cannot pass parameters to Android Activity Constructor: because Android calls the constructor of the Activity and the only constructor Android calls is the default constructor which of course you can override but "It doesn't matter whether you add it or not, and there is no context in which it can be employed in a useful way.".

So as there is no way you can pass your parameters to default constructor, you cannot employ it to work for you.



回答3:

If you really need to create an Activity that has a constructor (because, say, you're creating an Activity that will be launched by another app, such as the edit activity of a Tasker plugin), you can do it by using a derived class, as so:

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

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

If you need to generate the parameter, replace "parameter" with a function call that returns the appropriate value.



回答4:

Try to use extras to pass values between activities:

Intent intent = new Intent(getBaseContext(), CalorieSelectorActivity.class);
intent.putExtra("username", userName);
startActivity(intent);

Access that intent on next activity in the onCreate method:

String userName = getIntent().getStringExtra("username");

Another option is use static variables but I don't know if this is a good practice.



回答5:

What error do you get when you try and call the constructor? You can pass values into new instances of your Activity by calling its construction. It might or might not solve your problem but what happens if you annotate your constructor with @override?

That said, you really should be using Bundles or the intent.put methods to make data available to them since those values can be restored by the system if your Activity is paused to free up memory.