繁体   English   中英

Java中奇怪的初始化行为

[英]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);
        }
    }
}

只有在第一次调用init时,我才设置了AlertBox,我认为if块不应再执行。 但是我错了,它在每次调用init时都会运行。 为什么?

我来自Javascript,如果将上面的代码翻译成JS(类似),则if块仅计算一次。

alertBoxalertBox的成员变量,即该类的每个实例都有其自己的副本。 因此,如果您有多个ActivityA实例,则每个实例都有其自己的alertBox ,最初alertBox都设置为null

如果要共享alertBox ,则需要将其声明为static

private static AlertDialog alertBox;

虽然,这可能会导致多线程应用程序出现(其他)问题,所以请谨慎使用!

您应该检查您的应用程序如何遵循android活动生命周期。 每次重新创建一个Activity时,都会调用onCreate方法(即使之前存在)。 检查您的onDestroy()方法是否被调用。 如果答案是肯定的,那么您现在知道android如何处理其Activity。 有关详细说明,请参见http://developer.android.com/training/basics/activity-lifecycle/starting.html

但是,如果答案是否定的,则您的活动处理有问题。 也许您每次用户按下按钮等都重新创建相同的活动。也许您在某处finish()了活动。 但这只是疯狂的猜测。

alertBox被声明为实例变量。

如果只想为该类而不是为每个对象实例设置一次,则可能应将alertBox static变量。

该活动可能已销毁并重新创建,因此新对象的alertBox为null。

应该将其更改为静态变量,因为alertBox保持对创建它(我不知道它是否会甚至在活动的其他情况下正常工作)活动的参考,因此,如果你在一个静态保存它变量,它将防止原始活动被GC(垃圾收集器)收集。

在每个活动实例中创建一个新实例是正确的方法(您现在进行的方法就可以了)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM