情景与原因
前面的文章说过,我的一个业务要从页面A进入页面B,也就意味着我的应用出现了在ActivityA的基础上启动了ActivityB的情景,这个时候ActivityA就进入了停止状态,但这个时候如果出现系统内存不足的情况,就会把ActivityA回收掉,此时用户按下Back键返回A,仍然会正常显示A,但此时的A是执行onCreate()方法加载的,而不是执行onRestart()方法,也就是说我们的ActivityA页面是被重新创建出来的。
那有什么区别呢,这就是我们平时网上填表之类的最讨厌的情景会浮现了,比如你好不容易把信息填好,点击下一步,然后发现想修改上个页面信息,哎,这时候你会发现由于系统内存不足回收掉了A,于是你辛辛苦苦填好的信息都没了,这太痛了。这一情景的出现就说明回收了A再重新创建会导致我们在A当中存的一些临时数据与状态都可能被丢失。
这就是我们今天要解决的问题。
解决方法
虽然出现这个问题是是否影响用户体验的,但解决方法是非常简单的,因为我们的Activity中还提供了一个onSaveInstanceState()回调方法,它就可以保证在Activity被回收之前一定被调用,而我们就可以利用这一特性去解决上述问题。
方法介绍
onSaveInstanceState()方法中会携带一个Bundle类型的参数,而Bundle提供了一系列方法用于保存我们想要的数据,其中如putString()就是用于保存字符串的,而putInt()方法显而易见也是保存整型数据的,而每个保存方法都需要传入两个参数,其中第一个参数我们称之为键,是用于在Bundle中取值的特定标记,第二个参数是我们要保存的内容,属于键值对类型,学过数据库的一般都知道。
写法
如下,我们可以这么去写:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) val tempData = "your temp data" outState.putString("data_key", tempData) }
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (savedInstanceState != null) { val tempData = savedInstanceState.getString("data_key") } ... }
在onSaveInstanceState()中保存你想要的数据,在onCreate()中给取出来,这样就不用害怕再创建的时候数据丢失了,不过如果是横竖屏切换造成数据丢失还是依照前文ViewModel的写法更好。
结语
其实基础往往是最容易忽视的,我们之前光在那说高楼大厦如何建成,但地基并不牢靠,所以还是需要落实到基础上最好。