为什么onDestroy inActivity在ActivityB

时间:2015-04-29 11:08:25

标签: android android-activity

下一个过程很容易理解和重现,但会导致错误:

  • activityA在其onCreate()方法
  • 中启动activityB
  • activityB已创建,我在其onResume()方法中调用finish()
  • activityB onDestroy()被称为
  • activityA onResume()被称为
  • 在activityA中,我点击一个菜单按钮拨打finish() - 或按后退键。
  • activityA已删除但onDestroy()未被调用且A仍然存在(adb shell dumpsys'myPackageName'表示生活活动过多)

代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gleroy.com.algo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <activity
            android:name="gleroy.com.algo.activity.FakeA"
            android:label="@string/app_name"></activity>

        <activity
            android:name="gleroy.com.algo.activity.FakeB"
            android:label="@string/app_name"></activity>
    </application>
</manifest>

活动A:

public class FakeA extends Activity {

    private final static String TAG = FakeA.class.getCanonicalName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate, taskId :" + getTaskId());
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(FakeA.this, FakeB.class);
        startActivity(intent);
    }

    @Override
    protected void onResume() {
        Log.d(TAG, "onResume");
        super.onResume();
    }


    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        super.onCreateOptionsMenu(menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.stop_session_menu_item:
                /* stop and quit */
                finish();
                return false;
        }

        return super.onOptionsItemSelected(item);
    }
}

活动B:

public class FakeB extends Activity {

    private final static String TAG = FakeB.class.getCanonicalName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate, taskId :"+getTaskId());
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume, isFinishing :" + isFinishing());
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }
}

活动A从MainActivity启动,其中包含一个简单的按钮:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, FakeA.class);
            startActivity(intent);
        }
    });

所以我知道我们无法确定onDestroy()是否会被呼叫但是我的ActivityA显然已经泄漏了。

此外,我发现如果我使用TimerTimerTask来延迟ActivityA中的startActivity或ActivityB中的finish(),那么我就不再有这个错误。< / p>

以下是事件:

  • FakeA onCreate,taskId:154
  • FakeA onResume
  • FakeA onPause,isFinishing:false
  • FakeB onCreate,taskId:154
  • FakeB onResume,isFinishing:false
  • FakeA onResume
  • FakeB onDestroy
  • 致电完成或按回键:FakeA onPause,isFinishing:true

2 个答案:

答案 0 :(得分:1)

代替finish()尝试finishAffinity()。 我所知道的: finish()只会破坏当前的直播Activity 同时,finishAffinity()会销毁所有有效的Activities

答案 1 :(得分:0)

最好的解决方案就是检测启动Activity FakeB是否有用。