如果Android活动已经以根目录的形式出现在后台,则无法启动?

时间:2019-06-05 19:22:47

标签: android android-intent

我有一个包含3个活动的示例应用程序:Main,A和B。它们都没有任何launchMode。

现在我这样做:

  1. 打开应用,显示主要活动
  2. 使用“后退”按钮离开应用程序,这样就不会有活动在运行
  3. 接收开始新活动A(new_task标志)的广播
  4. 通过单击活动A中的按钮打开活动B(无标志)
  5. 接收开始新活动A(new_task标志)的广播
  6. 新活动A未未开始 (如果我回过头,仍然有以前的活动A)

在步骤#6中,应该显示活动A,但不显示。

如果我尝试呈现活动C(在#5中),则会按预期显示。

如果在#2中,我改用homebutton离开应用程序,则一切正常。

这怎么可能?以及如何确保始终显示活动?我可以使用FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP,但我想维护后台程序。

更新-来源: 您可以看一下source,但我使用的是Xamarin(基本上是用C#编写的本机Android,与Java非常相似)。 这是内置清单的内容(删除了Xamarin的内容):

<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28" android:compileSdkVersionCodename="9" package="com.companyname.StartTest" platformBuildVersionCode="28" platformBuildVersionName="9">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <application android:allowBackup="true" android:debuggable="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name="android.app.Application" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
        <activity android:label="A" android:name="A"/>
        <activity android:label="B" android:name="B"/>
        <activity android:label="@string/app_name" android:name="MainActivity" android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <receiver android:name="Receiver"/>
    </application>
</manifest>

2 个答案:

答案 0 :(得分:1)

好的,让我们按照操作顺序来看看。

  1. 打开应用,显示主要活动

    后退状态:Main Activity (root)

  2. 使用“后退”按钮离开应用程序,这样就不会有活动在运行

    后退状态:<No activity present as back was pressed>

  3. 接收开始新活动A(new_task标志)的广播

    后退状态:ActivityA (root)

  4. 通过单击活动A中的按钮打开活动B(无标志)

    后退状态:ActivityA (root) -> ActivityB (top)

  5. 接收开始新活动A(new_task标志)的广播

    后退状态:ActivityA (root) -> ActivityB (top)

    此处未启动Actvitity A,因为它是用意图标记'FLAG_ACTIVITY_NEW_TASK'启动的,该意图标记具有以下文档:

  

使用此标志时,如果活动的任务已经在运行   您现在开始,那么新的活动将不会开始;   而是将当前任务简单地带到   屏幕上显示的是最后一次进入的状态。

  1. 新活动A尚未启动(如果我回过头,仍然有先前的活动A)

在步骤#6中,应该显示活动A,但不显示。

  

所以当前任务看起来像这样ActivityA (root) -> ActivityB(top)ActivityA    已经存在于任务中,因此任务   整体只是放在最前面,这意味着ActivityB是   仍然在任务的顶部。

如果我尝试展示活动C(在#5中),则会按预期显示。

  

ActivityC是任务中没有的新活动,因此它   为您创建。

如果在#2中,我改为通过Homebutton离开该应用程序,则一切正常。

按下homebutton的事情是MainActivity在这种情况下不会被破坏,只是被推送到后台。

因此,在#2之后,您的backstack状态仍然看起来像以MainActivity实例为根:

Main Activity (root)

现在,在#5之前,后堆栈应如下所示:

Main Activity (root) -> ActivityA -> ActivityB (top)

#5之后,您的堆栈看起来像这样:

Main Activity (root) -> ActivityA -> ActivityB -> ActivityA (top)

我相信,这似乎是由于MainActivity默认情况下使用intent标志启动的方式:

  

FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

这还会触发任务重定,因此它可以控制使用新任务标记(与父应用程序具有相同的亲和力)创建的新活动,以及如何将此类活动移至其任务。

您可以找到有关此here

的更多信息

我如何确保始终显示活动?我可以使用FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP,但我想维护后退堆栈。

由于这是堆栈数据结构,因此您无法重新排列活动,但是可以通过在创建ActivityA的接收器中添加标志FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK来解决此问题,因为这将确保新的活动无论活动是否存在,都会为活动创建实例/任务。 (不是推荐的解决方案  -但有效)

但是,如果要维护ActivityA的相同实例,则必须在清单中的活动中添加taskAffinity参数。

<activity android:name=".ActivityB" android:taskAffinity="com.example.pendingintent"></activity>
<activity android:name=".ActivityA" android:taskAffinity="com.example.abctest" />

然后使用new_task标志开始活动A和B

Here是一张出色的幻灯片,解释了taskAffinity及其对活动创建的影响。

答案 1 :(得分:0)

更新选项3:。这应将“活动”置于顶部。

intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);

选项1 :在启动活动A时设置FLAG_ACTIVITY_REORDER_TO_FRONT。这会将活动A置于堆栈的顶部。

activityAIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

选项2 :在Android文档中,只有“标准”启动模式会创建活动的多个实例。

请参阅下表。

此文档说明了每种模式的用法:https://developer.android.com/guide/topics/manifest/activity-element.html#lmode

如果每次都需要新的实例,则向活动A添加标准的launchMode。

android:launchMode="standard"

enter image description here