Java中初始化的奇怪行为

时间:2013-01-15 12:25:15

标签: java android

/**
 * 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块只被评估一次。

4 个答案:

答案 0 :(得分:3)

alertBox是类的成员变量,即类的每个实例都有自己的副本。因此,如果您有多个ActivityA个实例,则每个实例最初都会设置为alertBox {/ 1}}。

如果您想要分享null,则需要将其声明为alertBox

static

尽管如此,这可能会导致多线程应用程序出现(其他)问题,因此请小心使用!

答案 1 :(得分:1)

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

但是,如果答案是否定的,那么您的活动处理就会出现问题。也许你每次用户按下按钮等时都会重新创建相同的活动。也许你finish()某个地方的活动。但这只是猜测。

答案 2 :(得分:0)

alertBox被声明为实例变量。

如果您只想为类设置一次而不是为每个对象实例设置一个alertBox,那么可能应该static {/ 1}}。

答案 3 :(得分:0)

可能会破坏并重新创建活动,因此新对象将alertBox设置为null。

你应该将其更改为静态变量,因为alertBox保存了对其创建活动的引用(我不确定它是否能在其他活动实例中正常工作),所以如果你将它保存在一个静态变量中,它将阻止GC(垃圾收集器)收集原始活动。

在活动的每个实例中创建一个新的是正确的方法(你现在的方式很好)。