当使用不同的 Intent 启动 Activity 时,如何防止 Activity 的多个实例
当我使用 Google Play 商店应用(以前称为 Android Market)上的“打开”按钮启动应用程序时,我遇到了一个错误。从 Play 商店启动它与从手机的应用程序图标菜单启动它似乎使用了不同的 Intent
。这会导致启动同一 Activity 的多个副本,这些副本彼此冲突。
例如,如果我的应用程序由 Activity ABC 组成,则此问题可能会导致 ABCA 堆栈。
我尝试在所有 Activity 上使用 android:launchMode="singleTask"
来解决此问题,但每当我按下 HOME 按钮时,它都会产生将 Activity 堆栈清除到根目录的不良副作用。
预期行为是: ABC ->首页->当应用程序恢复时,我需要: ABC ->首页-> ABC
有没有一种好方法可以防止启动多个相同类型的 Activity,而无需在使用 HOME 按钮时重置为根 Activity?
I've come across a bug in my application when it is launched using the "Open" button on the Google Play Store app (previously called Android Market). It seems that launching it from the Play Store uses a different Intent
than launching it from the phone's application menu of icons. This is leading to multiple copies of the same Activity being launched, which are conflicting with each other.
For example, if my app consists of the Activities A-B-C, then this issue can lead to a stack of A-B-C-A.
I tried using android:launchMode="singleTask"
on all the Activities to fix this problem, but it has the unwanted side-effect of clearing the Activity stack to root, whenever I hit the HOME button.
The expected behavior is: A-B-C -> HOME -> And when the app is restored, I need: A-B-C -> HOME -> A-B-C
Is there a good way to prevent launching multiple Activities of the same type, without resetting to the root activity when using the HOME button?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
将其添加到 onCreate 中,您应该可以开始了:
Add this to onCreate and you should be good to go:
我只是要解释它失败的原因,以及如何以编程方式重现此错误,以便您可以将其合并到您的测试套件中:
当您通过 Eclipse 或 Market App 启动应用程序时,它会使用意图标志启动:FLAG_ACTIVITY_NEW_TASK。
通过启动器(主页)启动时,它使用标志:FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_BRUGHT_TO_FRONT | FLAG_ACTIVITY_BROUGHT_TO_FRONT | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,并使用操作“MAIN”和类别“LAUNCHER”。
如果您想在测试用例中重现此情况,请使用以下步骤:
然后执行执行其他活动所需的操作。出于我的目的,我只是放置了一个启动另一个活动的按钮。然后,返回到启动器(主页):
并通过启动器模拟启动它:
如果您尚未合并 isTaskRoot() 解决方法,这将重现该问题。我们在自动测试中使用它来确保此错误不再发生。
希望这有帮助!
I'm just going to explain why it fails, and how to reproduce this bug programmatically so you can incorporate this in your test suite:
When you launch an app through Eclipse or Market App, it launches with intent flags: FLAG_ACTIVITY_NEW_TASK.
When launching through the launcher (home), it uses flags: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_BROUGHT_TO_FRONT | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, and uses action "MAIN" and category "LAUNCHER".
If you would like to reproduce this in a test case, use these steps:
Then do whatever is needed to get to the other activity. For my purposes, I just placed a button that starts another activity. Then, go back to the launcher (home) with:
And simulate launching it via the launcher with this:
If you haven't incorporated the isTaskRoot() workaround, this will reproduce the problem. We use this in our automatic testing to make sure this bug never occurs again.
Hope this helps!
您尝试过singleTop启动模式吗?
以下是 http://developer.android.com/ 的一些描述指南/topics/manifest/activity-element.html:
Have you tried the singleTop launch mode?
Here is some of the description from http://developer.android.com/guide/topics/manifest/activity-element.html:
也许是这个问题?或者同一错误的其他形式?
Perhaps it is this issue? Or some other form of the same bug?
我意识到这个问题与 Xamarin Android 没有任何关系,但我想发布一些内容,因为我在其他地方没有看到它。
为了在 Xamarin Android 中修复此问题,我使用了 @DuaneHomick 中的代码并将其添加到
MainActivity.OnCreate()
中。与 Xamarin 的区别在于它必须位于Xamarin.Forms.Forms.Init(this, bundle);
和LoadApplication(new App());
之后。所以我的OnCreate()
看起来像:*编辑:从 Android 6.0 开始,上述解决方案对于某些情况来说是不够的。我现在还将
LaunchMode
设置为SingleTask
,这似乎使事情再次正常工作。不幸的是,不确定这可能会对其他事情产生什么影响。I realize that the question does not have anything to do with Xamarin Android but I wanted to post something since I did not see it anywhere else.
To fix this in Xamarin Android I used the code from @DuaneHomick and added into
MainActivity.OnCreate()
. The difference with Xamarin is that is must go afterXamarin.Forms.Forms.Init(this, bundle);
andLoadApplication(new App());
. So myOnCreate()
would look like:*Edit: Since Android 6.0, the above solution is not enough for certain situations. I have now also set
LaunchMode
toSingleTask
, which seems to have made things work correctly once again. Not sure what effects this might have on other things though unfortunately.我认为接受的答案(Duane Homick)有未处理的情况:
您有不同的额外内容(因此应用程序重复):
这是一个解决方案(SDK_INT>=11 用于通知),我相信它可以处理这些情况并且状态栏通知也。
清单:
启动器活动:
服务:
通知:
I think the accepted answer (Duane Homick) has unhandled cases:
You have different extras (and app duplicates as a result):
Here is a solution (SDK_INT>=11 for notifications) which i belive handle these cases and statusbar notifications also.
Manifest:
Launcher activity:
Service:
Notification:
我遇到了同样的问题,并使用以下解决方案修复了它。
在您的主要活动中,将此代码添加到
onCreate
方法的顶部:不要忘记在清单中添加此权限。
希望对你有帮助。
I had the same problem, and I fixed it using the following solution.
In your main activity add this code on the top of the
onCreate
method:don't forget to add this permission in your manifest.
hope it helps you.
我也遇到了这个问题
android:configChanges="mcc|mnc"
- 如果您已连接到蜂窝网络,请参阅 http://developer.android.com/guide/topics/manifest/activity-element.html#config 用于启动系统或推开或其他任何操作时的配置。I had this problem also
android:configChanges="mcc|mnc"
- if you have connection to cellular, see http://developer.android.com/guide/topics/manifest/activity-element.html#config for which configuration there is when booting the system or push open or whatever.尝试这个解决方案:
创建
Application
类并在那里定义:然后在
onCreate
中的第一个(启动器)Activity 中,在setContentView(...)
之前添加以下内容:PS < code>Controller 是我的
Application
类。Try this solution:
Create
Application
class and define there:Then in your first (Launcher) Activity in
onCreate
beforesetContentView(...)
add this:P.S.
Controller
is myApplication
class.尝试使用 SingleInstance 启动模式,并将亲和力设置为 allowtaskreparenting
这将始终在新任务中创建活动,但也允许其重新设置父级。
检查dis:亲和力属性
try using SingleInstance launch mode with affinity set to allowtaskreparenting
This will always create the activity in new task but also allow its reparenting.
Check dis :Affinity attribute
我找到了一种方法来防止开始相同的活动,这对我来说非常有用
I found a way to prevent starting same activities, this works great for me