使用alwaysRetainTaskState和lauchMode保留android应用程序状态
在我的 Android 应用程序中,我有一个主要活动作为我的应用程序的入口点,它在我的清单文件中配置如下:
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
因此,对于特定用例,假设用户通过以下方式从主屏幕启动应用程序:单击应用程序启动器内的图标。启动应用程序后,用户从主活动导航到活动 A,最后导航到活动 B。此时,用户决定检查他们的 facebook,因此他们单击主页按钮将我的应用程序置于后台,然后启动脸书应用程序。
查看他们的 Facebook 后,用户想要返回到我的应用程序,因此他们按主页键,然后从应用程序启动器启动应用程序(就像他们第一次启动应用程序时所做的那样)。
当用户返回我的应用程序时,我希望应用程序返回到应用程序放入后台时用户所在的最后一个活动,在本例中是活动 B。在清单文件中,我设置了alwaysRetainTaskState=true确保操作系统不会终止我的应用程序的活动。
现在我的问题是:如何获得上述行为?每当我单击应用程序的图标时,无论如何,它总是从主活动开始。我认为这是因为category.LAUNCHER 属性。我尝试过 android:launchMode=singleTask,但没有效果;它总是从 Main 开始。
如果有人能够阐明意图过滤器、启动模式和任务,那就太好了!
In my Android app, I have a main activity that serves as an entry point to my application, which is configured in my manifest file like this :
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
So for a particular use case, lets say a user starts up the app from the home screen by clicking the icon inside the application launcher. After starting the app, the user navigates from the Main activity to activity A and then finally to activity B. At this point, the user decides to check their facebook, so they click the home button to put my app in the background, and launches the facebook app.
After checking their facebook, the user wants to return to my app, so they press the home key, and launch the application from the application launcher (just like they did the first time it was launched).
When a user returns to my app, I want the app to return to the last activity the user was at when the app was put into the background, which in this case is activity B. In the manifest file, I have set alwaysRetainTaskState=true to make sure the OS doesn't kill my app's activities.
Now to my question: how do I get the behavior I described above? Whenever I click my app's icon, it always starts at the Main activity, no matter what. I think this is because of the category.LAUNCHER attribute. I have tried android:launchMode=singleTask, but it hasn't made a difference; it always starts at Main.
If someone could clarify intent filters, launch modes, and tasks, that would be great!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
仅供参考
singleTask
不是您想要的,因为它启动了一个新任务:http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
您如何启动 Activity B?有任何非标准启动模式或意图标志吗?
FYI
singleTask
is not what you want, since it starts a new task:http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
How are you launching Activity B? Any non-standard launch modes or Intent flags?
对于任何来这里遇到类似问题的人,我发现了一些奇怪的东西,可能就是你所看到的……也许吧。
假设我有一个包含活动 A -> 的应用程序B-> C 等。如果我的应用程序是从应用程序列表(又名启动器)启动的,我的应用程序总是“恢复”到 A,我遇到了问题。不过,从“resents”屏幕(长按主页键)恢复将表现出正确的恢复行为(按预期恢复到 B 或 C)。我的清单没什么特别的,我总是在根活动中设置RetainTaskState =“true”,并且启动模式是默认(标准)。
我通过网站将该 apk 加载到我的手机上。下载并安装后,我会按“打开”立即启动该应用程序。由于某种原因(卸载应用程序后),我厌倦了再次下载、安装,但后来我按了“完成”按钮。然后,从启动器/“所有应用程序”列表启动应用程序与从最近的应用程序恢复具有相同的恢复行为 - 换句话说,我的问题是由于单击“打开”而不是“完成”时的安装过程而引起的。
我在 API10 (2.3.5) 和 API15 (4.0.4) 上验证了这个“解决方案”
For anyone coming here with similar problems, I found something strange that might be what you are seeing... maybe.
Say I have an app with activities A -> B -> C etc. I was having issues with my app always "resuming" to A if it was launched from the app list aka launcher. Resuming from the "resents" screen (long home press) would exhibit correct resume behaviour though (resume to B or C as expected). My manifest was nothing special, I have alwaysRetainTaskState="true" set in my root activity, and launch mode is default (standard).
I was loading the apk onto my phone via a website. After downloading and installing, I would press "Open" to launch the app right away. For some reason (after uninstalling the app) I tired downloading again, installing, but then I pressed the "Done" button instead. Then Launching the app from the launcher/"all apps" list has the same resume behaviour as resuming from recents - in other words my problems were being caused somehow because of the installation process when clicking "Open" instead of "Done".
I verified this "solution" on API10 (2.3.5) and API15 (4.0.4)
我通过添加无屏幕的 DispatcherActivity 并将其设为默认的(通过使用完全相同的意图过滤器)解决了这个问题。在其
onCreate
方法中,您可以根据一些合理的默认值(例如您的 Main 活动)或根据一些保存的标识应启动哪个 Activity 的令牌来创建和调用 Intent。该令牌在您想要在重新启动时调用的任何 Activity 的onStop
方法中保存/刷新。您可以将此令牌保存到首选项中。这里的理由是最后一个可见的活动将在中断时执行 onStop 方法。
这里要注意的是:我确实实现了这个模式,并且效果相当好。然而,它似乎与历史不太相符,最后我放弃了并删除了这段代码。到目前为止还没有人抱怨过。
I solved this by adding the screenless
DispatcherActivity
and making it the default one (by using the very same intent filter). In itsonCreate
method you create and call the Intent based on some reasonable default (your Main activity for example) OR based on some saved token that identifies which Activity should be started. That token is saved/refreshed inonStop
method of any Activity you want to call on restart. You can save this token to Preferences.The rational here is that last activity that was visible will execute onStop method when interrupted.
Word of caution here: I did implement this pattern and it worked reasonably well. However it seems not play too well with history and finally I just gave up and yanked this code out. Nobody complained so far.