Android 10-怪异的活动生命周期

问题描述

我有一个奇怪的问题,发生在Android 10上,当我开始新的景观活动时,下面的活动将重新创建。

假设有两个Activity类:

ActivityA: orientation = unspecified
ActivityB: orientation = force landscape,full screen,opaque

如果我从ActivityB开始ActivityA,则生命周期事件的日志:

D/ActivityA: onPause() called
D/ActivityB: onCreate() called
D/ActivityB: onStart() called
D/ActivityB: onResume() called
D/ActivityA: onStop() called
D/ActivityA: onDestroy() called
D/ActivityA: onCreate() called
D/ActivityA: onStart() called
D/ActivityA: onResume() called
D/ActivityA: onPause() called
D/ActivityA: onStop() called

可以清楚地看到ActivityA被重新创建,而且在ActivityA#onResume之后又以某种方式调用ActiviyB#onResume

好的,现在我们在堆栈顶部有ActivityB,然后按返回按钮:

D/ActivityB: onPause() called
D/ActivityA: onStart() called
D/ActivityA: onResume() called
D/ActivityA: onPause() called
D/ActivityA: onStop() called
D/ActivityA: onDestroy() called
D/ActivityA: onCreate() called
D/ActivityA: onStart() called
D/ActivityA: onResume() called
D/ActivityB: onStop() called
D/ActivityB: onDestroy() called

ActivityA是否重新创建?

正如我在设备中看到的那样,有一个动画,ActivityAActivityB可见之前旋转为横向模式,并且当ActivityB退出时,ActivityA再次旋转为纵向模式。此行为可能导致ActivityA一次又一次地重新创建。

这很麻烦,您是否知道如何防止在这种情况下重新创建ActivityA,或者这是Android本身的错误

更新1

我可以轻松处理ActivityA上的配置更改,问题是ActivityA具有非常复杂的视图结构,不必要地重新创建它会导致UI滞后,而且活动的生命周期回调混乱也将导致逻辑​​中断。

更新2

我刚刚发现recreate()类两次调用AppCompatDelegateImpl方法,这就是为什么我会得到奇怪的生命周期行为的原因:

enter image description here

解决方法

您可能对此行为无能为力。如果不会给您带来太多问题,我建议您采取以下措施:

  • android:configChanges="orientation"添加到ActivityA的清单条目中
  • onConfigurationChanged()中实施ActivityA并自行处理方向改变

这将防止Android在更改方向时杀死并重新创建ActivityA

,

不仅您遇到了这个问题(很多人都这样),这是一个待修复的错误,实际上不应该被弄乱,我可以知道您所使用的设备吗?在评论中您可能会说。

,

在景观/肖像上重新创建活动是Android设计的功能(不是bug),因为通过编程方式,只需重新绘制UI而不是找出元素的重新放置/调整大小,它就更容易。即使在没有B的情况下,只要在A上翻转方向,您也应该获得相同的效果。Android文档(https://developer.android.com/guide/components/activities/state-changes#cco)中也对此进行了很好的描述

这应该不是太大的问题,只要您不保留对活动本身的任何引用即可;此时的资源已经被缓存,因此几乎没有Flash I / O,大部分工作将是重新创建视图。

,

默认情况下,每次轮换后都会重新创建活动,如官方活动生命周期onDestroy()文档所述。

如果您希望活动的UI状态在整个配置更改(例如轮换)中保持不变,则应使用ViewModel,onSaveInstanceState()和/或本地存储的组合来保留用户的瞬时UI状态,如下面所述。 Saving and restoring transient UI state

您可以使用AndroidManifest中活动标签的config changes属性覆盖此行为。有关更多详细信息和其他选项,请参见Handle configuration changes

最后,您可以在此处了解有关Activity Lifecycle in Context of Screen Rotation的更多信息。

,

这看起来像是特定于设备的错误。

我尝试了您在Pixel 3a(API 29&30)模拟器上的代码。这就是我得到的:

ActivityB开始ActivityA时:

D/MainActivityA: onPause() called
D/MainActivityB: onCreate() called
D/MainActivityB: onStart() called
D/MainActivityB: onResume() called
D/MainActivityA: onStop() called

在后退按钮上按下:

D/MainActivityB: onPause() called
D/MainActivityA: onStart() called
D/MainActivityA: onResume() called
D/MainActivityB: onStop() called
D/MainActivityB: onDestroy() called

No weird animation indicating ActivityA is changing orientation

您应该file an issue使用适当的Android版本和使用的设备

问题中关于更新2的想法

日志显示onConfigurationChanged(Configuration)正在被调用。 Documentation指出,将在运行时配置更改时重新创建活动。

您可以做的是在“活动”中覆盖onConfigurationChanged(Configuration)并记录配置对象以查看更改了哪些设备配置。可能是OrientationScreen sizeScreenLayoutKeyboard availability

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...