Почему я не могу передать параметры в Android Activity Constructor

Я знаю, что я не могу передать параметры конструктору Activity в android, но я хотел бы понять, почему.

Что я пытался сделать:

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

Я определил класс следующим образом:

public class CalorieSelectorActivity extends Activity {

public CalorieSelectorActivity(String name) {
    super();

}

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

}
}

И он отлично работает, когда я удаляю параметры из конструктора. Я, наконец, сделал это с помощью intent.putExtra, но мне очень любопытно узнать, почему это невозможно сделать, передав параметры конструктору?

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

Обратитесь к своему коду:

CalorieSelectorActivity csa = new CalorieSelectorActivity(userName);

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

startActivity(i);

Даже если вы создаете объект своей деятельности, то, что вы "проходите" в объекте Intent, это не activity object, а только class of your activity. В startActivity() инфраструктура Android попытается создать экземпляр объекта вашей деятельности. И он вызывает конструктор по умолчанию (без параметров), когда он это делает. Он терпит неудачу, когда ваш класс не имеет конструктора без параметров.

Конечно, вы нашли правильное решение, передайте параметры как часть объекта Intent.

Ответ 2

Я удивлен, что никто не ответил на заданный вопрос! Итак, чтобы ответить на это Why I cannot pass parameters to Android Activity Constructor: потому что Android вызывает конструктор Activity, а единственный конструктор Android вызывает конструктор по умолчанию, который, конечно, вы можете переопределить, но "Не имеет значения, добавляете ли вы это или нет, и нет контекста, в котором это можно было бы использовать полезным способом.".

Так как вы не можете передать свои параметры конструктору по умолчанию, вы не можете использовать его для своей работы.

Ответ 3

Если вам действительно нужно создать Activity, у которого есть конструктор (потому что, например, вы создаете Activity, который будет запущен другим приложением, например, действие редактирования Tasker, вы можете сделать это, используя производный класс:

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

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

Если вам нужно сгенерировать параметр, замените "parameter" на вызов функции, который возвращает соответствующее значение.

Ответ 4

Попробуйте использовать дополнительные функции для передачи значений между действиями:

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

Получите доступ к этому намерению в следующем действии в методе onCreate:

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

Другой вариант - использовать статические переменные, но я не знаю, является ли это хорошей практикой.

Ответ 5

Какую ошибку вы получаете при попытке вызвать конструктор? Вы можете передавать значения в новые экземпляры своей деятельности, вызывая ее конструкцию. Это может или не может решить вашу проблему, но что произойдет, если вы аннотируете свой конструктор с помощью @override?

Тем не менее, вы действительно должны использовать Bundles или methods.put, чтобы сделать доступными для них данные, поскольку эти значения могут быть восстановлены системой, если ваша активность приостановлена, чтобы освободить память.