Android - 重启后打开系列活动
这是我的情况。我有相同的活动,这些活动依次进行,无论他们在做什么。让我们从字母表的开头给它们命名。当用户使用我的应用程序时,他会浏览活动并在它们之间创建自己的路径,因此他可以使用后退按钮按相应的后退顺序返回。
他从行动开始。 A - D - F,使用后退按钮,他可以从 F 返回到 D 和 A。好的。现在,当 Android 系统发现应用程序不再使用或在某个特定时间需要大量 RAM 时,系统会杀死它。我的目标是找到如何将应用程序恢复到以前的状态,包括打开活动的顺序?
可能不太清楚,所以这里是一个例子:
用户打开了活动A(登录)-D-F-G,将其最小化,一段时间后,应用程序被杀死。当他再次启动这个应用程序时,他需要登录活动 A,然后他必须看到活动 G(= 他上次在那里),当他按下后退按钮时,他将执行活动 F,然后执行活动 D,依此类推on... 就像恢复一排活动。我知道我必须保留活动中存储的所有信息(D、F、G),但是真的有可能像这样保留应用程序状态吗?
感谢您对此
解决方案的任何评论:
我正在跟踪标志,它标识我的应用程序所处的状态。如果它是 s 0,则意味着我正在正常打开新活动。在每个活动开始时,我都会放入共享首选项字符串,其中包含我的所有活动历史记录。每个活动都有自己的 id(同样是sharedPref)。在另一个共享首选项中,当 onPause 发生时,我将保存为字符串公式数据(或带有 GUI 的数据)。我将 flag 设置为 1。当应用程序启动且 flag 为 1 时,我从 sharedPref 恢复应用程序堆栈。从另一个共享首选项为每个人设置数据。就是这样,应用程序状态被恢复:-)
there is my situation. I have same activities which goes one by another, no matter what they are doing. Lets name them from the start of alphabet. When users uses my application, he goes through activities and makes his own path between them, so he could with back button go back in respecitve back order.
He starts with act. A - D - F and with back button he goes back as from F to D and A. Ok. Now, when Android system resolves the application is no longer in use or needs lot of RAM in some particular time, system kills it. My goal is to find, how to restore application to its former state including order of opened activities?
It might not be clear, so here is the example:
User has open activities A (login) - D - F - G, minimize it, after some time, app is killed. When he start this application again, he needs to login at activity A and than he has to see activity G (= he was there last time), and when he push back button, he will go do activity F, then activity D and so on... Is like revieving an row of activites. I know I have to persist all the information stored in my activities (D, F, G), but is it acutally possible to persist app state like that?
Thanks for any comment on this
Solution:
I am tracking flag, which identifies the state my application is in. If it is s 0, it means I am opening new activity normally. On start of each activity I put into shared preferences string, which contains all my activity history. Each activity has it's own id (again sharedPref). In another shared pref I am saving as a String formular data (or data with GUI), when onPause occurs. I set flag as a 1. When app starts and flag is 1, I revive application stack from sharedPref. Set data for each of them from another Shared Pref. And that's it, application state is revived :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你可以坚持任何你需要坚持的事情,这只是如何坚持以及什么会有益的问题。多年来,有多种技术被用来保存状态。几乎所有这些都可供您使用,但需要您仔细管理。根据您的应用程序的用途,您可能还可以使用特殊的技巧。
第 1 步
确定每个活动需要什么才能有效运行。确定哪些内容可以重新计算,哪些内容绝对不应该重新计算。例如,如果您的其中一个 Activity 是某种游标适配器,并且根据表的键工作,则无需保留整个 Activity,只需保留其中的一个
_id
与特定的活动运行相关。第 2 步
由于您想要跟踪活动历史记录,因此您需要对该历史记录进行某种表示。您提出的是一个堆栈模型,因此您将需要编写自己的堆栈对象并找到一种简单的方法来识别该堆栈中的每个活动。不要尝试保存实际的活动引用,因为这总是会导致泄漏。然后,您可以将此堆栈保存到数据库、共享首选项、文件,甚至将其打包到捆绑包中。标识每个活动的整数常量可能是实现此目的的一种方法。
第 3 步
确定保存方法,并为堆栈和每个 Activity 构建适当的保存和加载方法。
第 4 步
覆盖“后退”按钮以检索堆栈上顶部的 Activity 标识符及其相应数据。 (请注意:您的堆栈可能更适合放置在扩展的
Application
中),然后使用其所需的数据启动下一个Activity
。第 5 步
当您的“登录”活动(或应用程序)启动时,加载堆栈。身份验证完成后,重新加载堆栈上的顶部 Activity,通过 Intent Extras 传递其所需的数据。您不必立即打开所有活动,只需打开用户所在的活动即可。
第 6 步
在每个
Activity
的onCreate
或onWindowAttached
中,将其自身添加到堆栈中。在每个Activity
的onDestroy
中,让它从堆栈中删除自身。由于您要保留数据,因此您可以轻松finish()
来指示Activity
已完成。第 7 步
在每个
Activity
的onPause
中,保存您认为重要的状态。您甚至可以保存滚动位置,并在Activity
重新启动时重新滚动。在您的onCreate
中,它通过您提供的额外内容恢复其状态。这真的很简单。如果您需要一些样品,我很乐意提供。
模糊逻辑
You can persist anything you need to, it just a matter of how and what is going to be beneficial. There are multiple techniques that have been used to persist state over the years. Nearly all of them are available to you, but will require careful management on your part. Depending on what your application does, there may be special tricks available to you, as well.
Step 1
Determine what each Activity needs in order to run effectively. Determine what you can recalculate and what you absolutely should not recalculate. For instance, if one of your Activities is a Cursor Adapter of some kind and works according to a key to a table, you don't need to persist the entire Activity, you simply need to hold onto whichever
_id
relates to that particular Activity run.Step 2
Since you are wanting to track Activity history, you will need some representation of that history. What you are proposing is a stack model, so you will want to write your own stack object and find an easy way to identify each activity in that stack. Do not try and save the actual Activity references as this will invariably lead to leaks. You can then save this stack to a database, shared preferences, file or even parcel it to a bundle. Integer constants that identify each Activity might be one way to accomplish this.
Step 3
Decide on your method of save, and build the appropriate save and load methods for your stack and each Activity.
Step 4
Override the Back button to retrieve the top Activity identifier and its appropriate data on the stack. (As a note: your stack might be better placed in an extended
Application
) Then start the nextActivity
with its required data.Step 5
When your "login" Activity (or Application) starts, load the stack. When authentication completes, reload the top Activity on the stack, passing its required data through Intent Extras. You don't have to open ALL of the Activities at once, just the ones that the user is on.
Step 6
In your
onCreate
oronWindowAttached
for eachActivity
, have it add itself to the stack. In youronDestroy
for eachActivity
, have it remove itself from the stack. Since you are persisting your data, you can easilyfinish()
to indicate that theActivity
is complete.Step 7
In your
onPause
for eachActivity
have it save the state that you feel is important. You can even save the scroll position and just have it rescroll when theActivity
restarts. In youronCreate
have it regain its state via the extras that you supplied.It is really as simple as all of that. If you need some samples, I can gladly provide.
FuzzicalLogic
假设您需要做的就是重建从 A 到 Z 的活动路径(或其他),您不需要让事情变得太复杂。如果你想以正确的方式去做,请按照模糊逻辑的建议去做。如果你想让它快速运行并使之后的事情变得复杂,你可以从这个简单的方法开始。
基本上,您将每个活动映射到一个代码,并维护一个简单的文本文件。每次调用活动时,它都应该将其代码附加到文本文件中。所以你实际上只是按照你在问题中解释的内容写入文件。在您的示例中,文本文件中有“ADFG”。
当您退出活动并返回时,只需读取文件,剪掉最后一个字母,然后写出来。在您的示例中,如果您有“ADFG”,请按回,该文件现在将包含“ADF”。
当您的应用程序启动时,只需读取文件并为每个角色创建关联的活动,就像平常一样。读取该文件一次,然后在创建该文件时将字符串传递给每个活动。因此,根活动将读取“A”并启动该活动(在包中传递字符串“DFG”),然后该活动将读取下一个字符并启动 D 活动(传递“FG”),依此类推,直到最后一个活动发现字符串中没有剩余字符。
一旦一切正常,您就可以担心如何存储每个活动的状态信息。 Fuzzy 的解决方案是迄今为止最优雅的,但优雅和 ASAP 通常不会混合,所以这是你的决定。我会将堆栈数据与堆栈中每个项目的状态数据分开。 IMO这样更容易。
希望有帮助!
Assuming all you need to do is reconstruct the path of activities from A to Z (or whatever), you don't need to make things too complicated. if you want to do it the right way, do the suggestion by Fuzzical Logic. if you want to get it running quickly and complicate things after that, you can start with this simple method.
Basically, you map each activity to a code, and maintain a simple text file. Each time an activity is invoked, it should append it's code to the text file. So you're really just writing to a file exactly what you explained in your question. In your example, you'd have "ADFG" in a text file.
When you exit an activity and go back, just read the file, chop off the last letter, and write it out. In your example, if you had "ADFG", pressed back, the file would now contain "ADF".
When your app starts, simply read the file and for each character, create the associated activity as you would normally. Read the file once and pass the string to each activity as it is created. So the root activity would read "A" and start that activity (passing the string "DFG" in the bundle), then that activity would read the next character and start the D activity (passing "FG"), and so on until the last activity sees that there's no characters left in the string.
Once that's all working, you can worry about how to store state information for each activity. Fuzzy's solution is by far the most elegant, but elegant and ASAP don't usually mix, so it's your call. I'd separate the stack data from the state data for each item in the stack. It's just easier that way IMO.
Hope that helps!