如果在 Activity#onCreate() 方法中调用 finish() 方法,其生命周期会发生什么变化?
无 Fragment 的情况
未调用 finish 方法
正常情况下 Activity 的声明周期:
Activity.onCreate -> Activity.onStart -> Activity.onPostCreate -> Activity.onResume -> Activity.onPostResume;
将 Activity 置于后台后再返回到前台:
Activity.onPause -> Activity.onStop -> Activity.onRestart -> Activity.onStart -> Activity.onResume -> Activity.onPostResume。
调用 finish 方法
在 Activity#onCreate() 中调用 finish() 方法,生命周期如下:
Activity.onCreate -> Activity.onDestroy。
如果未重写 finish() 方法,从 finish() 方法返回后继续执行 onCreate() 中剩余的代码。
含有一个 Fragment
添加 Fragment 的方法:
if (savedInstanceState != null) {
FragmentManager fm = getSupportFragmentManager();
myFragment = (MyFragment) fm.findFragmentByTag(MyFragment.TAG);
}
if (myFragment == null) {
MyFragment = new MyFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(android.R.id.content, myFragment, MyFragment.TAG);
ft.commit();
}
}
未调用 finish 方法
Activity.onCreate -> Fragment.onAttach -> Fragment.onCreate -> Fragment.onCreateView -> Fragment.onViewCreated -> Fragment.onActivityCreated -> Fragment.onStart -> Activity.onStart -> Activity.onPostCreate -> Activity.onResume -> Fragment.onResume -> Activity.onPostResume;
息屏后又点亮:
Fragment.onPause -> Activity.onPause -> Fragment.onStop -> Activity.onStop -> Activity.onRestart -> Fragment.onStart -> Activity.onStart -> Activity.onResume -> Fragment.onResume -> Activity.onPostResume;
关闭页面:
Fragment.onPause -> Activity.onPause -> Fragment.onStop -> Activity.onStop -> Fragment.onDestroyView -> Fragment.onDestroy -> Fragment.onDetach -> Activity.onDestroy。
调用 Activity#finish() 方法
在 Activity#onCreate() 方法中调用 finish() 方法。
Activity.onCreate -> Fragment.onAttach -> Fragment.onCreate -> Fragment.onDestroy -> Fragment.onDetach -> Activity.onDestroy。
应用案例
如果 Activity#onCreate() 方法中有调用 finish() 方法情况,则要保持某些成员变量的健壮性,预防出现空指针等异常。比如:
public class MainActivity extends AppCompatActivity {
private List<String> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mData = getIntent().getStringArrayListExtra("data");
if (mData == null) {
finish();
}
// more code
}
@Override
protected void onDestroy() {
super.onDestroy();
mData.clear();
}
}
上述代码片段的逻辑是:如果上个页面传过来的数据为空,则关闭页面。
问题在于,如果执行 finish() 方法,则会紧接着执行 Activity#onDestroy() ,则会出现空指针异常。如果该 Activity 中含有 Fragment,更要注意 Fragment#onDestroy() 方法中是否有可能发生空指针异常。