你所不知道的Activity生命周期

yo2788 7年前
   <h2><strong>背景知识</strong></h2>    <p>典型的生命周期,就不说了,相信大家一定知道,初学者也可以百度,很多,这里大只记录一下一些生命周期中的细节</p>    <h2><strong>先后顺序</strong></h2>    <ol>     <li> <p>onStart 和onResume、onPause 和 onStop的实质性区别:</p> <p>其实从实际过程中来说,两者就是差不多的,我们甚至可以只保留一组,但是尽然Android实现了重复接口,肯定有它的意义,其实两者的回调时机不一样, onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从是否位于前台来回调的。</p> </li>     <li> <p>如果从Activity A跳转到Activity B,那么B的onResume和A的onPause哪一个方法先执行呢?</p> <p>我们可以通过源码分析,也可以通过打Log日志来分析,我这边就直接记录结果了,有兴趣的朋友可以自己深入分析一下,或者通过Log来确认一下, 旧Activity的onPause方法先调用,然后新Activity才会启动 ,从另外一个角度讲,Android的官方文档对onPause的解释有这样一句话: 不能再onPause中做重量级操作,因为必须onPause执行完成之后新的Activity才能Resume ,所以我们知道,不能再onPause和onStop里面做耗时性操作,尤其是onPause如果一定要的话就再onStop中执行。</p> </li>    </ol>    <h2><strong>异常生命周期</strong></h2>    <ol>     <li>资源相关的系统配置发生改变导致Activity被杀死并重新创建<br> 默认情况下,不会做任何处理,当时系统配置发生改变导致Activity被销毁并重新创建,这个时候 Activity的onPause,onStop,onDestroy方法都会被调用,同时,由于是异常中止,所以系统还会调用onSaveInstanceState来保存当前数据 ,onSaveInstanceState会在onStop之前调用,与onPause没有一定的先后顺序。而且只有在 Activity是异常中止的情况下onSaveInstanceState才会被调用 。当Activity被重建之后,系统会调用onRestoreInstanceState来获取销毁时保存的数据,并且以Bundle的形式传递给当前方法和onCreate方法,因此我们可以通过onCreate和onRestoreInstanceState来分析Activity有没有被创建,从时序上来说onRestoreInstanceState的调用在onStart之后。 同时我们需要知道onSaveInstanceState和onRestoreInstanceState都只有在Activity被异常中止的时候才会被调用,正常是不会的,而且数据的存储和恢复,都是系统自动帮我们完成的</li>     <li>资源内存不足导致优先级低的Activity被杀死<br> Activity的优先级分为三种:      <ol>       <li>前台Activity——正在和用户交互的Activity,优先级最高。</li>       <li>可见但非前台Activity——比如被一个弹出的对话框覆盖,用户可见,但是无法进行直接交互。</li>       <li>后台Activity——已经被暂停的Activity比如已经执行了onStop,优先级最低。</li>      </ol> </li>    </ol>    <p>当系统内存不足的时候,系统就会按照上述的优先级来杀死目标Activity所在的进程,并且通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。</p>    <h2><strong>总结</strong></h2>    <p>我们知道了,当系统配置发生改变的时候我们的Activity会被杀死和重建,当然我们也可以配置,告诉系统,我们不想重建,比如:横屏的时候我不想重建Activity,我就可以配置configChanges属性来实现</p>    <pre>  android:configChanges="orientation"</pre>    <p>如果我们想指定多个值我们可以通过'|'来连接起来比如:</p>    <pre>  android:configChanges="orientation|keyboardHidden"</pre>    <p>虽然configChanges的值有很多,但是我们常用的也就locale、orientation和keyboardHidden,这三个,下面是所有属性的介绍,大家可以了解一下:</p>    <table>     <thead>      <tr>       <th>项目</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>mcc</td>       <td>此项表示mcc代码发生了改变(SIM卡唯一标识IMSI 中的国家代码)</td>      </tr>      <tr>       <td>mnc</td>       <td>此项表示mnc代码发生了改变(SIM卡唯一标识IMSI 中的运营商代码)</td>      </tr>      <tr>       <td>locale</td>       <td>本地位置发生改变,一般指切换了系统语言</td>      </tr>      <tr>       <td>touchscreen</td>       <td>触摸屏发生了改变(正常不会发生可以忽略)</td>      </tr>      <tr>       <td>keyboard</td>       <td>键盘类型发生了改变(用户外接键盘)</td>      </tr>      <tr>       <td>keyboardHidden</td>       <td>键盘的可访问性发生改变</td>      </tr>      <tr>       <td>navigation</td>       <td>系统当行方式发生了改变</td>      </tr>      <tr>       <td>screenLayout</td>       <td>屏幕布局发生了改变</td>      </tr>      <tr>       <td>fontScale</td>       <td>系统字体缩放比例发生改变</td>      </tr>      <tr>       <td>uiMode</td>       <td>用户界面模式发生了改变(夜间模式)</td>      </tr>      <tr>       <td>orientation</td>       <td>屏幕方向发生了改变(很常用,选转屏幕)</td>      </tr>      <tr>       <td>screenSize</td>       <td>屏幕的尺寸信息发生了改变</td>      </tr>      <tr>       <td>smallestScreenSize</td>       <td>设备的物理屏幕尺寸发生改变</td>      </tr>      <tr>       <td>layoutDirection</td>       <td>当布局的方向发生改变时</td>      </tr>     </tbody>    </table>    <p> </p>    <p>来自:http://www.jianshu.com/p/b04a06eb2c9e</p>    <p> </p>