Saving and Restoring Emergency Data in Android

Original address: Please scan the WeChat public account of stormzhang after the article - AndroidDeveloper

This article is authored by one of my readers, "MeloDev". This knowledge point can be called one of the basic knowledge points frequently asked in interviews. It is recommended to read it several times to understand it. WeChat does not support external links, you can click "Read the original text" to view.

write in front

In the process of using our APP, there may always be various situations of hand slipping, being pressed in the background, or even being killed suddenly. Therefore, for some temporary data or key persistent data in the APP, we need to use the correct way to save or restore.


What are the emergencies

Because this article discusses the preservation and recovery of data when some emergencies occur. So now to summarize what emergencies should be?


  • Click the back button

  • Click the lock screen button

  • Click the home button

  • Other APPs enter the foreground

  • started another Activity

  • screen orientation rotation

  • APP is Killed


When these emergencies occur, what key methods will be called?


I wrote a simple demo, and I used the above-mentioned emergencies to test. In the code, I rewrote the life cycle methods and onSaveInstanceState methods of all Activity, and printed the corresponding log on the console. The following is the demo diagram:






I won't post the test process here, let me tell you the test results directly:


When my APP is in the foreground and can interact with the user, when the above-mentioned emergency occurs, the onSaveInstanceState method will not be called only when the back button is clicked. In other cases, this method will always be called, why is that? And the onPause method is bound to be called. What kind of ideas does this give us to save data?


onSaveInstanceState

Well, I believe that when you see the title of this article, you should have thought of this method. Because when we learn the basics of Android, data recovery with the onSaveInstanceState method is something you must have learned. So some of the suspense I created earlier seems to have failed, but you should know more about onSaveInstanceState:  


1. 何时调用:


Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key)


找到了以上一段话,翻译过来就是当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。


结合我们以上的例子,其实都在说明一个词,就是被动。当Activity并不是由我主动点击back键而丧失焦点时,onSaveInstanceState方法就一定会调用。就例如我上述列举的那些除了点击back键的「突发情况」


2. 何地调用:




在我写的这个demo中,onSaveInstanceState的调用是处于onPause和onStop之间的,(下面关于Activity的生命周期方法,会讲解一些值得大家注意的),我查阅了一下资料,能保证的是onSaveInstanceState方法会在onStop之前调用,但是是否在onPause之前就不一定了。


结论: google工程师们对onSaveInstanceState如此设计就是让其完成对一些临时的、非永久数据存储并进行恢复。什么样的数据属于临时数据呢?举个例子,比如EditText中输入的内容,CheckBox是否勾选,ScrollView的滑动位置,目前视频的播放位置等等。


当我还没有自学Android时,玩着一些APP就会产生一个疑问,比如我在一个输入框中输入了大量文字没有提交或者保存。此时来了一个电话,如果退回的时候,输入框里面的文字消失了,那我可能会砸了电话,所以这个保存数据的操作,是Android开发者做的吗?


然而是不需要的,因为Android的View本身自己就实现了onSaveInstanceState方法,这些控件自己就具有保存临时数据和恢复临时数据的能力。


例如TextView中的部分源码:




其他View控件都有相似的实现原理。值得一提的是,只有当你给这个wiget在xml中指定id时,它才具有保存数据并且恢复的能力,并且不同的wiget还不能共用这个id,否则会出现数据覆盖的情况。具体的源码有兴趣大家可以自己去看,这里因为篇幅的原因不再贴出,关于onSaveInstanceState我们先说这些,赶紧看看使用姿势。


onSaveInstanceState的使用姿势

比如我们要保存当前视频的播放进度,这个显然控件没有帮我们实现onSaveInstanceState,所以就只能靠自己了,代码如下所示。





当在onCreate取出临时数据时,记得加一个非空判断。


看到这里,也许你认为本文该就此结束了,不过在回过头看看,我们刚才一直强调的是临时数据,毕竟onSaveInstanceState本身就是为临时数据服务的,但是一些永久性质的数据,比如插入数据库的操作,我们应该在什么方法中对其进行保存呢?


onPause

在介绍onPause方法之前,还是想聊聊Activity的生命周期方法,相信大家对它应该有了初步的了解,不过在相应的生命周期方法中,我们应该做什么操作呢?推荐给大家一篇文章,我觉得不错。


「Activity生命周期详解」


关于onPause,我找到了一下关于它的特性:


onPause(), onStop(), onDestroy() are "killable after" lifecycle methods. This indicates whether or not the system can kill the process hosting the activity at any time after the method returns, without executing another line of the activity's code. Because onPause() is the first of the three, once the activity is created, onPause() is the last method that's guaranteed to be called before the process can be killed—if the system must recover memory in an emergency, then onStop() and onDestroy() might not be called. Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage. However, you should be selective about what information must be retained during onPause(), because any blocking procedures in this method block the transition to the next activity and slow the user experience.


The translation is: no matter what happens, such as the sudden death of the program, what can be guaranteed is that the onPause method will definitely be called, but the onStop and onDestory methods are not necessarily, so this feature makes onPause the last method to persist related data. Reliable timing. Of course, the onPause method cannot do a lot of operations, which will affect the stacking of the next Activity.


Our test results just now also illustrate the truth that onSaveInstanceState is not called 100% (for example, when the back button is clicked). Obviously, we cannot save some permanent data here.


The conclusion of this article is obvious, let's summarize it in one sentence:


Temporary data is saved and restored using onSaveInstanceState, and permanent data is saved using the onPause method.



WeChat does not support external links. You can click "Read the original text" to view it. If you think it is helpful, you may wish to forward it and support it. Press and hold the QR code to subscribe.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324170626&siteId=291194637