Android pop to parent activity with status preserving

用 Android Studio 创建的 Blank Activity,在新建向导里会问你它是否有上级页面,可以在里面填上它上一级的 Activity,那么生成的 Activity 顶部的导航栏左侧就有返回按钮,并且点击后可以返回上一级页面。

但是这个返回按钮是有问题的。正常情况下,点击返回应该直接返回到之前创建的上层 Activity,也就是直接 pop 到上一层。但是这个返回按钮,是把上一层 Activity 重新创建了一遍显示出来的,导致无法显示之前的状态。

比如上层 Activity 有一个 ViewPager,里面有两个 Fragment。在第二个 Fragment 里点击进入了详情的 Activity,然后点击返回按钮,发现返回到了上层 Activity 的初始状态-默认选择的第一个 Fragment。

可以在 AndroidManifest.xml 中看到,实现方式是定义了一个 PARMENT_ACTIVITY:

AndroidManifest.xml
1
2
3
4
5
6
7
8
<activity android:name=".ProductListActivity"
android:label="@string/title_activity_product_list"
android:parentActivityName=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.stoneark.doorsbylin.MainActivity" />
</activity>

解决方法也很简单,在 AndroidManifest.xml 中把上一层 Activity 的属性 android:launchMode 改为 singleTop 即可,即:

AndroidManifest.xml
1
2
3
4
5
6
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar"
android:launchMode="singleTop" >
</activity>

launchMode 的默认值是 standard,每次都会强制重新创建一个 activity 的实例,所以导致了问题。根据 Android 文档中的描述,
android:launchMode 的取值有:standardsingleTopsingleTasksingleInstance,默认值是 standard:

  • standard 允许该 activity 有多个实例,并且每当显示这个 activity 时就总是重新创建一个。
  • singleTop 允许该 activity 有多个实例,但如果它当前在栈顶,则不重新创建。
  • singleTask 只允许该 activity 有一个实例,并且它只能存在于栈底。
  • singleInstance 与 singleTask 相同,另外还要求栈中只能有它自己,而不能再启动另外任何 activity。