当Android系统内存不足时,会回收后台运行应用的内存

来源:互联网 发布:纳粹军服淘宝有卖的吗 编辑:程序博客网 时间:2024/04/27 23:45

1、前言

当Android系统的运行内存不足时,会把运行在后台的应用杀掉,将所有已经存在的Activity都杀掉,当用户重新返回应用的时候,所有被杀掉的Activity都会被重建,而且应用会运行在一个全新的进程当中,所有的数据都被重置为初始状态。那么这个时候往往都会出现错误数据。


2、案例:

XX应用,在登录页初始化所有数据

 --> 登录成功进入主页面

--> 此时登陆页已经完成任务,finish登陆页

 --> 从主页面进入到A页面

 --> A页面通过网络加载数据

 --> 点击Home键,打开其他耗内存的应用,此时如果内存不够,会把XX应用的主页面和A页面都干掉,当再返回XX应用时,主页面和A页面都会重建,经历onCreate方法等。


3、如何触发以上案例:

XX应用现在的手机基本上运行内存都足够了,但是还是会有开太多应用导致内存不够的时候,如果使用真机来重现以上案例,需要开的应用就多了,那么如何轻易的就实现以上案例呢?很简单,可以通过虚拟机,下载Genymotion,建一个虚拟机,将虚拟机的运行内存改为150M-200M左右,基本上就足够一个应用运行但不够两个应用一起运行了。

重现案例的条件已经具备了,接下来就是如何通过代码Log来实验了。


4、代码分析:

@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);Log.e("YYQ", "onCreate");}@Overrideprotected void onStart(){super.onStart();Log.e("YYQ", "onStart");}@Overrideprotected void onResume(){super.onResume();Log.e("YYQ", "onResume" + android.os.Process.myPid());}@Overrideprotected void onPause(){super.onPause();Log.e("YYQ", "onPause");}@Overrideprotected void onStop(){super.onStop();Log.e("YYQ", "onStop");}@Overrideprotected void onDestroy(){super.onDestroy();Log.e("YYQ", "onDestroy");}@Overrideprotected void onRestart(){super.onRestart();Log.e("YYQ", "onRestart");}
// 这个方法不知道是什么时候触发的@Overridepublic void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState){super.onSaveInstanceState(outState, outPersistentState);Log.e("YYQ", "onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState)");}
<pre name="code" class="java">// 当后台运行应用时,此方法会被触发    @Override    protected void onSaveInstanceState(Bundle outState)    {        // 在这里保存相关信息        outState.putString("test","save msg");        super.onSaveInstanceState(outState);        Log.e("YYQ", "onSaveInstanceState(Bundle outState)");    }    // 当内存不足应用被干掉后,重新回到应用,此方法被触发    @Override    protected void onRestoreInstanceState(Bundle savedInstanceState)    {        super.onRestoreInstanceState(savedInstanceState);        // 在这里取回相关信息        Log.e("YYQ", "test是:"+savedInstanceState.getString("test"));        Log.e("YYQ", "onRestoreInstanceState");    }



在Activity中加入如上方法,就可以在Log中查看Activity的状态了。

正常的Activity状态就不说了,

当你按下Home键,会触发

onPauseonSaveInstanceState(Bundle outState)onStop


比较重要的是onSaveInstanceState(Bundle outState),当系统未经你的允许就想要把Activity干掉的时候,这个方法会被触发,你可以在这里进行保存的操作。

此时应用已经在后台运行了,当你没有打开其他应用,也就是内存足够的时候,重新返回的时候不会触发onRestoreInstanceState方法,只有应用被干掉了,才会触发onRestoreInstanceState方法,还有onCreate方法。

onCreateonStartonRestoreInstanceStateonResume


在onCreate方法加入:

@Overrideprotected void onResume(){super.onResume();Log.e("YYQ", "onResume:" + android.os.Process.myPid());}

会发现你刚启动应用时的pid和应用被杀掉后重建的pid不一样,说明应用在新进程中了。

你可以在onRestoreInstanceState方法中恢复数据。




5、解决方式:

虽然可以在onSaveInstanceState(Bundle outState)和onRestoreInstanceState方法中进行保存和恢复数据,但是对于一些全局性的数据最好能够一次性恢复,这样对于所有的Activity都有好处。

可以在基类Activity中一次性恢复。(一般应用都会有个自己的基类BaseActivity,用于抽取Activity的共性)

在onCreate方法中加入判断:

if (savedInstanceState != null && TextUtils.isEmpty(                BaseApplication.getInstance().getCurrentUser().getSystemUserID())){       BaseApplication.getInstance().initUserAllData();}

其中第二个判断条件和if语句块是根据个人情况来的,我在这里的判断是当用户的id为null时,就说明Activity已经被重建了,数据被清除了,那么我就再次初始化用户的数据。保证了用户数据的完整性。

第一个判断条件只有当调用了onSaveInstanceState(Bundle outState)方法,并且应用被杀掉后,才不为null。

如此一来,就不怕内存不够的时候了,而且初始化用户数据也不会被多次初始化。







0 0