<activity-alias> 打破了 singleTop 模式的契约

Having <activity-alias> breaks a contract of singleTop mode

问题来了。我的清单中有一个 定义如下:

<activity
    android:name=".HomeActivity"/>

<activity-alias
    android:name=".MainActivity"
    android:targetActivity=".HomeActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

现在,用户使用启动器图标启动 MainActivity,它转发到 HomeActivity

我还打算从导航抽屉开始 HomeActivity。它以 Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP 标志开始 - 重用 activity.

的现有实例

问题是这没有按预期工作,它实际上创建了 HomeActivity 的新实例(即使它当前位于顶部并且可见!)。 发生这种情况是因为 activity backstack 包含 .MainActivity 的条目,而不是它最终转发到的 HomeActivity 的条目。

问题: 我怀疑这可能是也可能不是 Android 中的错误,但我很难找到合适的解决方法。在这里寻求帮助! :)

我只需要启动单个 activity,当用户在 navdrawer 中选择一个项目时,那个单个 activity 应该得到 onNewIntent(),而不是新的 activity 生成!

摆脱 activity-别名可以解决问题,但这对我来说不是一个可接受的选择...

这是 activity 从启动器启动后的 adb dumpsys 结果,然后用户在 navdrawer 中选择 'Home' 直接启动 activity,而不是通过别名(这dump 确认有两个名称不同的条目):

  Main stack:
    TaskRecord{4181c408 #61 A ru.treto.tile U 0}
    Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=ru.treto.tile/.HomeActivity }
      Hist #2: ActivityRecord{412514b8 ru.treto.tile/.HomeActivity}
        Intent { flg=0x24000000 cmp=ru.treto.tile/.HomeActivity }
        ProcessRecord{412b06e0 10165:ru.treto.tile/u0a63}
      Hist #1: ActivityRecord{41723200 ru.treto.tile/.MainActivity}
        Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=ru.treto.tile/.MainActivity }
        ProcessRecord{412b06e0 10165:ru.treto.tile/u0a63}

与其在启动它的 类 中引用您的 HomeActivity,您需要更改这些意图以启动“MainActivity”。

例如:

Intent intent = new Intent();
intent.setClassName(mContext, "ru.treto.tile.MainActivity");

或者,如果您正在使用另一个 IntentFilter 方案,您可以将这些 IntentFilter 元素移动到清单中的 alias 条目:

<activity-alias 
    android:name=".MainActivity"
    android:target="ru.treto.tile.HomeActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="ru.treto.tile.ACTION_OF_AWESOME" />
    </intent-filter>
</activity-alias>