Activity生命周期以及启动模式对生命周期的影响(二)

时间:2023-03-09 08:28:15
Activity生命周期以及启动模式对生命周期的影响(二)

前面一篇文章概述了Android四大组件之一的Activity生命周期方法的调用先后顺序,但对于非标准启动模式下Activity被多次调用时的一些生命周期方法并未详细阐述,现在针对该情况着重记录.

  • 现象

  发布会demo中出现了这样的一种现象:当界面即将出现时,语音重复唤起该界面时,由于在onPause中调用了finish(),界面一直未显示出来,这不是我们想要的.

  • 分析

  由于系统组这边存在的一个bug,全屏的Activity出现时会带起在后台运行的应用界面,所以我们这边的Activity不得不采用singleTask的启动模式来规避该问题(暂时还未找到有效方法解决),由此当非第一次启动时,先走该Activity的onPause,

  然后再走onNewIntent,最后onStart-->onResume-->界面展示且获取到焦点.那么根据这个顺序我们就可以采用下面的方式来解决了.

  • 解决办法

  我们现在onPause方法中,用主线程的handler去post一下,是否需要finish()掉界面.这样操作可以把post的消息内容置于onNewIntent消息之后执行.

  如果是通过onNewIntent启动,那么我们就不操作;

  如果是通过onCreate启动,那么我们就finish()掉.

  具体代码如下

  

  private boolean isStartedAgain = false;

    @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
this.isStartedAgain = true;
} @Override
protected void onPause() {
super.onPause();
uiHandler.post(new Runnable() {
@Override
public void run() {
if (isStartedAgain) {
isStartedAgain = false;
} else {
uiHandler.removeMessages(0);
finish();
}
}
});
}

像这样,如果你是第一次启动该Activity,不会走onNewIntent方法;当再次启动时,onPause-->onNewIntent-->post的消息队列.

那么onPause时,把要执行的runnable抛出来,onNewIntent时,标志isStartedAgain为true(默认为false),

最后判断run方法中如何走;如果是再次启动isStartedAgain=true的话,不会关掉界面;如果是第一次启动,即isStartedAgain=false的话,移除动画操作的消息(不做此操作有出现使用已关闭的Activity对象异常的风险),并且finish()掉界面.

  • 小结

  一切的理论都要经得起实践的考验,一切不以解决问题为目的的博客文章都是在打酱油.问题得到了解决,灰常开心.