1
2374
你需要重写
捆绑包本质上是存储NVP(“名称-值对”)映射的一种方法,它将被传递到
您通常会使用此技术存储应用程序的实例值(选择、未保存的文本等)。 |
2
396
这个
对于更长寿命的状态,请考虑使用sqlite数据库、文件或首选项。见 Saving Persistent State . |
3
382
注意它是
不是
安全使用
文档说明(在“活动生命周期”部分中):
换句话说,将持久数据的保存/还原代码放入
编辑
:为了进一步澄清,这里是
|
4
180
我的同事写了一篇文章解释Android设备上的应用程序状态,包括关于活动生命周期和状态信息的解释、如何存储状态信息以及保存到状态
本文涵盖三种方法: 使用实例状态包为应用程序生存期(即临时)存储本地变量/ui控制数据
使用共享首选项在应用程序实例(即永久)之间存储本地变量/ui控制数据
使用保留的非配置实例在应用程序生存期内的活动之间在内存中保持对象实例活动
|
5
132
这是Android开发的经典“gotcha”。这里有两个问题:
浏览所有这些线程时,我怀疑开发人员大部分时间都在同时讨论这两个不同的问题…因此,“这对我不管用”的所有困惑和报道。 首先,要澄清“预期”行为:OnSaveInstance和OnRestoreRestance是脆弱的,并且只适用于瞬时状态。预期用途(AFAIT)是在手机旋转(方向改变)时处理活动娱乐。换句话说,当您的活动在逻辑上仍处于“顶层”状态,但仍必须由系统重新启动时,您就可以使用它了。保存的包不会在进程/memory/gc之外持久化,因此如果您的活动转到后台,您就不能真正依赖于它。是的,也许您的活动的内存将在其后台访问和退出GC之后继续存在,但这不可靠(也不可预测)。 因此,如果您有一个场景,其中有意义的“用户进度”或状态应该在应用程序的“启动”之间保持,那么指导是使用onpause和onresume。您必须自己选择并准备一个持久存储。 但是-有一个非常令人困惑的bug,它使所有这些复杂化了。详情如下: http://code.google.com/p/android/issues/detail?id=2373 http://code.google.com/p/android/issues/detail?id=5277 基本上,如果您的应用程序是用singletask标志启动的,然后从主屏幕或启动程序菜单启动它,那么随后的调用将创建一个新的任务…实际上,你的应用程序有两个不同的实例驻留在同一个堆栈中…很奇怪很快。当你在开发过程中启动你的应用程序时(比如从Eclipse或Intellij),开发人员会经常遇到这种情况。但也可以通过应用商店的一些更新机制(因此它也会影响您的用户)。
在我意识到我的主要问题是这个bug,而不是预期的框架行为之前,我花了几个小时的时间在这些线程中挣扎。一篇伟大的文章
2013年6月更新 :几个月后,我终于找到了“正确”的解决方案。您不需要自己管理任何有状态的StartedApp标记,您可以从框架中检测到这一点,并适当地保释。我在我的启动程序活动的开头使用这个。创建:
|
6
73
|
7
62
这两种方法都是有用和有效的,并且都最适合不同的场景:
如果以持久的方式保存状态数据,则可以在
这并不是说一种方法比另一种更好,就像所有的方法一样,了解您需要什么样的行为并选择最合适的方法是非常重要的。 |
8
54
就我而言,拯救国家充其量只是一种拼凑。如果需要保存持久数据,只需使用 SQLite 数据库。安卓做到了 SOOO 容易的。 像这样:
之后打个简单的电话
|
9
51
我想我找到了答案。让我简单地说一下我做了什么: 假设我有两个活动,activity1和activity2,我正在从activity1导航到activity2(我在activity2中做了一些工作),然后单击activity1中的按钮,再次返回activity 1。现在,在这个阶段,我想回到活动2,当我上次离开活动2时,我想看到我的活动2处于相同的状态。 对于上面的场景,我所做的是在清单中我做了一些这样的更改:
在活动1的按钮点击事件中,我这样做了:
在Activity2 on Button Click事件中,我这样做了:
现在将要发生的是,无论我们在活动2中所做的更改是什么,都不会丢失,并且我们可以以与以前相同的状态查看活动2。 我相信这就是答案,这对我来说很好。如果我错了就纠正我。 |
10
37
|
11
34
真的?
从文档中引用:
“方法
|
12
29
为了帮助减少样板文件,我使用以下内容
首先,创建一个用于注释实例变量的接口:
然后,创建一个类,其中反射将用于将值保存到包中:
示例用法:
注: 这段代码是从一个名为 AndroidAutowire 根据 MIT license . |
13
29
同时,我做的一般不再有用
生命周期对于大多数活动来说太复杂,不必要。 谷歌声称,它甚至不可靠。 我的方法是在首选项中立即保存任何更改:
在某种程度上,共享引用的工作方式类似于捆绑包。 当然,首先,这些值必须从偏好中读取。 在复杂数据的情况下,您可以使用sqlite而不是使用首选项。 应用此概念时,活动将继续使用上次保存的状态,而不管它是初始打开状态,其间重新启动,还是由于后堆栈重新打开。 |
14
28
直接回答原始问题。savedinstanceState为空,因为从未重新创建您的活动。 只有在以下情况下,才能使用状态包重新创建您的活动:
Android会在内存压力下或长时间处于后台后破坏后台活动。 在测试Hello World示例时,有几种方法可以离开并返回活动。
在大多数情况下,如果你只是按下Home键,然后再次启动应用程序,则不需要重新创建活动。它已经存在于内存中,因此不会调用onCreate()。 在“设置”->开发人员选项下有一个名为“不保留活动”的选项。当它被启用时,Android将总是破坏活动,并在活动被重新建立时重新创建它们。在开发时,这是一个很好的选择,因为它模拟最坏的情况。(一个低内存设备,可随时回收您的活动)。 其他的答案是很有价值的,因为它们教会了你正确的存储状态的方法,但是我觉得它们并没有真正回答为什么你的代码没有按照你期望的方式工作。 |
15
24
这个
|
16
16
我的问题是,我只需要在应用程序的生命周期(即一次执行,包括在同一个应用程序中启动其他子活动和旋转设备等)中进行持久性。我尝试了上述各种答案的组合,但在所有情况下都没有得到我想要的答案。最后,对我有效的是在创建时获取对savedinstancestate的引用:
当我需要的时候,用它来获取变量的内容,沿着以下几行:
我用
|
17
15
虽然接受的答案是正确的,但是有一种更快更简单的方法可以使用一个名为 Icepick . Icepick是一个注释处理器,负责处理保存和恢复状态时使用的所有样板代码。 用冰镐做类似的事情:
与此相同:
Icepick将处理任何使用
|
18
13
创建活动时,会调用onCreate()方法。
savedinstanceState是bundle类的对象,第一次为空,但在重新创建时包含值。要保存活动的状态,必须重写OnSaveInstanceState()。
将您的值放入“outstate”bundle对象中,如outstate.putstring(“key”,“welcome back”),然后通过调用super保存。 当活动将被破坏时,它的状态将保存在bundle对象中,并且可以在onCreate()或onRestoreStanceState()中重新创建后恢复。OnCreate()和OnRestoreInstanceState()中接收的束是相同的。
或
|
19
12
基本上有两种方法来实现这个变更。
我真的不建议使用第二种方法。因为在我的一次经历中,它导致一半的设备屏幕变黑,同时从纵向旋转到横向,反之亦然。 使用上面提到的第一种方法,我们可以在方向更改或发生任何配置更改时保留数据。 我知道一种在savedinstance状态对象中存储任何类型数据的方法。 示例:如果要持久化JSON对象,请考虑一个案例。 用getter和setter创建一个模型类。
现在,在onCreate和onSaveInstanceState方法中的活动中,执行以下操作。它看起来像这样:
|
20
8
这是来自 史提夫莫塞利 的答案(通过) 工具匠史蒂夫 )这使事情有了透视(在整个OnSaveInstanceState与OnPause、East Cost与West Cost Saga中)
|
21
7
科特林代码: 保存:
然后在
如果不希望有选项,请添加默认值 |
22
5
简单快速解决这个问题是用 IcePick
首先,在中设置库
现在,让我们检查下面的示例如何在活动中保存状态
它适用于需要在捆绑包上序列化其状态的活动、片段或任何对象(例如,迫击炮的视图演示者) ICEPICK还可以为自定义视图生成实例状态代码:
|
23
5
获取存储在中的活动状态数据
当活动破坏时
|
24
5
不确定我的解决方案是否被拒绝,但我使用绑定服务来持久化ViewModel状态。无论是将它存储在服务的内存中,还是持久化并从sqlite数据库中检索它,都取决于您的需求。这就是任何风格的服务所做的,它们提供诸如维护应用程序状态和抽象公共业务逻辑等服务。 由于移动设备固有的内存和处理限制,我以类似于网页的方式处理Android视图。页面不维护状态,它只是一个表示层组件,其唯一目的是显示应用程序状态并接受用户输入。Web应用程序体系结构的最新趋势采用了古老的模型、视图、控制器(MVC)模式,其中页面是视图,域数据是模型,控制器位于Web服务后面。同样的模式也可以在Android中使用,因为视图是…视图中,模型是您的域数据,控制器是作为绑定到Android的服务实现的。每当您希望视图与控制器交互时,在开始/继续时绑定到它,在停止/暂停时取消绑定。 这种方法为您提供了实施关注点分离设计原则的额外好处,因为您的所有应用程序业务逻辑都可以转移到您的服务中,从而减少了跨多个视图的重复逻辑,并允许视图实施另一个重要的设计原则,即单一责任。 |
25
1
现在Android提供 ViewModels 对于保存状态,您应该尝试使用它而不是saveInstanceState。 |
26
0
保存什么和不保存什么?
曾经想知道为什么
当一个活动的实例被破坏,系统重新创建一个新实例(例如,配置更改)时。它试图使用一组保存的旧活动状态数据重新创建它。( 实例状态 )
实例状态是
键值
成对存储在
如果需要另一个变量保存为实例状态的一部分,则应该
重写
例如,
保存数据时有关OnSavedInstanceState(Bundle SaveDinstanceState)的详细信息
恢复活动状态时选择哪一个?
或
这两种方法都得到相同的bundle对象,所以在哪里编写恢复逻辑并不重要。唯一的区别是
有关OnRestoreStanceState(bundle savedinstanestate)的详细信息
奖金
这个
但如果用户按下后退按钮,就要考虑这个问题。假设用户不打算返回活动,因此在这种情况下
这里是 most relevant link . |
Abhilash Das · 输入文本时,编辑文本与工具栏重叠 1 年前 |
Community wiki · 局部变量可能尚未初始化 1 年前 |
jvargas · 如何获取上个月的第一天和最后一天以及一年的第一天 1 年前 |