[英]Strange behavior of initialization in Java
/**
* Example Activity to demonstrate the lifecycle callback methods.
*/
public class ActivityA extends Activity {
private String mActivityName;
private TextView mStatusView;
private TextView mStatusAllView;
private StatusTracker mStatusTracker = StatusTracker.getInstance();
private AlertDialog alertBox;
private static int number = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
init();
String output = getString(R.string.on_create) + number++;
showAlertDialog(alertBox, output);
mStatusTracker.setStatus(mActivityName, output);
Utils.printStatus(mStatusView, mStatusAllView);
}
@Override
protected void onStart() {
super.onStart();
mStatusTracker.setStatus(mActivityName, getString(R.string.on_start));
Utils.printStatus(mStatusView, mStatusAllView);
}
@Override
protected void onRestart() {
super.onRestart();
mStatusTracker.setStatus(mActivityName, getString(R.string.on_restart));
Utils.printStatus(mStatusView, mStatusAllView);
}
@Override
protected void onResume() {
super.onResume();
mStatusTracker.setStatus(mActivityName, getString(R.string.on_resume));
Utils.printStatus(mStatusView, mStatusAllView);
}
@Override
protected void onPause() {
super.onPause();
mStatusTracker.setStatus(mActivityName, getString(R.string.on_pause));
Utils.printStatus(mStatusView, mStatusAllView);
}
@Override
protected void onStop() {
super.onStop();
mStatusTracker.setStatus(mActivityName, getString(R.string.on_stop));
}
@Override
protected void onDestroy() {
super.onDestroy();
mStatusTracker.setStatus(mActivityName, getString(R.string.on_destroy));
mStatusTracker.clear();
}
public void startDialog(View v) {
Intent intent = new Intent(ActivityA.this, DialogActivity.class);
startActivity(intent);
}
public void startActivityB(View v) {
Intent intent = new Intent(ActivityA.this, ActivityB.class);
startActivity(intent);
}
public void startActivityC(View v) {
Intent intent = new Intent(ActivityA.this, ActivityC.class);
startActivity(intent);
}
public void finishActivityA(View v) {
ActivityA.this.finish();
}
private void showAlertDialog(AlertDialog ad, String msg) {
ad.setTitle("Logging Msg");
ad.setMessage(msg);
ad.show();
}
private void init() {
System.out.println("Value = before &&&&&&&&& " + alertBox);
if (alertBox == null) { // Why always null?
alertBox = new AlertDialog.Builder(this).create();
mActivityName = getString(R.string.activity_a);
mStatusView = (TextView) findViewById(R.id.status_view_a);
mStatusAllView = (TextView) findViewById(R.id.status_view_all_a);
Log.e("ActivityA", "Init done **************************************");
Log.e("ActivityA", "Init done **************************************");
System.out.println("Value = after &&&&&&&&&&& " + alertBox);
}
}
}
Only the very first time the init is called, I set alertBox and I thought the if block should not be executed any other time. 只有在第一次调用init时,我才设置了AlertBox,我认为if块不应再执行。 But I am wrong, it runs every time init is being called.
但是我错了,它在每次调用init时都会运行。 Why?
为什么?
I came from Javascript, if I translate the above code into JS (similar), the if block is only evaluated once. 我来自Javascript,如果将上面的代码翻译成JS(类似),则if块仅计算一次。
alertBox
is a member variable of a the class, ie each instance of the class has its own copy. alertBox
是alertBox
的成员变量,即该类的每个实例都有其自己的副本。 So if you have multiple instances of ActivityA
each has its own alertBox
all set to null
initially. 因此,如果您有多个
ActivityA
实例,则每个实例都有其自己的alertBox
,最初alertBox
都设置为null
。
If you want to share alertBox
you need to declare it as static
: 如果要共享
alertBox
,则需要将其声明为static
:
private static AlertDialog alertBox;
Although, this might result in (additional) problems in a multi-threaded application, so use with care! 虽然,这可能会导致多线程应用程序出现(其他)问题,所以请谨慎使用!
You should check how your application follows the android activity lifecycle. 您应该检查您的应用程序如何遵循android活动生命周期。 The onCreate method gets called every time an Activity is created again (even if it existed before).
每次重新创建一个Activity时,都会调用onCreate方法(即使之前存在)。 Check if your
onDestroy()
method gets called. 检查您的
onDestroy()
方法是否被调用。 If the answer is yes, you now know how android handles its Activitys. 如果答案是肯定的,那么您现在知道android如何处理其Activity。 See http://developer.android.com/training/basics/activity-lifecycle/starting.html for an in detail explanation.
有关详细说明,请参见http://developer.android.com/training/basics/activity-lifecycle/starting.html 。
However if the answer is no, there is something wrong on your activity handling. 但是,如果答案是否定的,则您的活动处理有问题。 Maybe you recreate the same activity every time the user pushes a button etc. Maybe you
finish()
the activity somewhere. 也许您每次用户按下按钮等都重新创建相同的活动。也许您在某处
finish()
了活动。 But this is just wild guessing. 但这只是疯狂的猜测。
alertBox
is declared as an instance variable. alertBox
被声明为实例变量。
Maybe you should make alertBox
a static
variable if you only want to set it once for the class and not for every object instance. 如果只想为该类而不是为每个对象实例设置一次,则可能应将
alertBox
static
变量。
Probably, the activity is destroyed and recreated, so the new object has alertBox as null. 该活动可能已销毁并重新创建,因此新对象的alertBox为null。
You should not change it to an static variable, because alertBox holds a reference to the activity where it was created (I'm not sure if it would even work correctly in other instances of the activity), so if you saved it in a static variable, it would prevent the original activity from being collected by the GC (garbage collector). 你不应该将其更改为静态变量,因为alertBox保持对创建它(我不知道它是否会甚至在活动的其他情况下正常工作)活动的参考,因此,如果你在一个静态保存它变量,它将防止原始活动被GC(垃圾收集器)收集。
Creating a new one in each instance of the activity is the right way to go (the way you are doing it now is fine). 在每个活动实例中创建一个新实例是正确的方法(您现在进行的方法就可以了)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.