网站 备案 注销,点个赞科技 网站制作,网页设计 效果图,网站原创页面子曰#xff1a;溫故而知新#xff0c;能够為師矣。《論語》 学习技术也一样#xff0c;对于技术文档或者经典的技术书籍来说#xff0c;指望看一遍就全然掌握#xff0c;那基本不大可能#xff0c;所以我们须要常常回过头再细致研读几遍#xff0c;以领悟到作者的思想精… 子曰溫故而知新能够為師矣。《論語》 学习技术也一样对于技术文档或者经典的技术书籍来说指望看一遍就全然掌握那基本不大可能所以我们须要常常回过头再细致研读几遍以领悟到作者的思想精髓。 近来回想了一下关于Activity的生命周期參看了相关书籍和官方文档也有了不小的收获对于曾经的认知有了非常大程度上的改善在这里和大家分享一下。 熟悉javaEE的朋友们都了解servlet技术我们想要实现一个自己的servlet须要继承对应的基类重写它的方法这些方法会在合适的时间被servlet容器调用。事实上android中的Activity执行机制跟servlet有些相似之处Android系统相当于servlet容器Activity相当于一个servlet我们的Activity处在这个容器中一切创建实例、初始化、销毁实例等过程都是容器来调用的这也就是所谓的“Dont call me, Ill call you.”机制。 我们来看一下这一张经典的生命周期流程图 相信不少朋友也已经看过这个流程图了也基本了解了Activity生命周期的几个过程我们就来说一说这几个过程。 1.启动Activity系统会先调用onCreate方法然后调用onStart方法最后调用onResumeActivity进入执行状态。 2.当前Activity被其它Activity覆盖其上或被锁屏系统会调用onPause方法暂停当前Activity的运行。 3.当前Activity由被覆盖状态回到前台或解锁屏系统会调用onResume方法再次进入执行状态。 4.当前Activity转到新的Activity界面或按Home键回到主屏自身退居后台系统会先调用onPause方法然后调用onStop方法进入停滞状态。 5.用户后退回到此Activity系统会先调用onRestart方法然后调用onStart方法最后调用onResume方法再次进入执行状态。 6.当前Activity处于被覆盖状态或者后台不可见状态即第2步和第4步系统内存不足杀死当前Activity而后用户退回当前Activity再次调用onCreate方法、onStart方法、onResume方法进入执行状态。 7.用户退出当前Activity系统先调用onPause方法然后调用onStop方法最后调用onDestory方法结束当前Activity。 可是知道这些还不够我们必须亲自试验一下才干深刻体会融会贯通。 以下我们就结合实例来演示一下生命周期的几个过程的具体情况。我们新建一个名为lifecycle的项目创建一个名为LifeCycleActivity的Activity例如以下 package com.scott.lifecycle;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;public class LifeCycleActivity extends Activity {private static final String TAG LifeCycleActivity;private Context context this;private int param 1;//Activity创建时被调用Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.i(TAG, onCreate called.);setContentView(R.layout.lifecycle);Button btn (Button) findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {Intent intent new Intent(context, TargetActivity.class);startActivity(intent);}});}//Activity创建或者从后台又一次回到前台时被调用Overrideprotected void onStart() {super.onStart();Log.i(TAG, onStart called.);}//Activity从后台又一次回到前台时被调用Overrideprotected void onRestart() {super.onRestart();Log.i(TAG, onRestart called.);}//Activity创建或者从被覆盖、后台又一次回到前台时被调用Overrideprotected void onResume() {super.onResume();Log.i(TAG, onResume called.);}//Activity窗体获得或失去焦点时被调用,在onResume之后或onPause之后/*Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);Log.i(TAG, onWindowFocusChanged called.);}*///Activity被覆盖到以下或者锁屏时被调用Overrideprotected void onPause() {super.onPause();Log.i(TAG, onPause called.);//有可能在运行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据}//退出当前Activity或者跳转到新Activity时被调用Overrideprotected void onStop() {super.onStop();Log.i(TAG, onStop called.); }//退出当前Activity时被调用,调用之后Activity就结束了Overrideprotected void onDestroy() {super.onDestroy();Log.i(TAG, onDestory called.);}/*** Activity被系统杀死时被调用.* 比如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.* 另外,当跳转到其它Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.* 在onPause之前被调用.*/Overrideprotected void onSaveInstanceState(Bundle outState) {outState.putInt(param, param);Log.i(TAG, onSaveInstanceState called. put param: param);super.onSaveInstanceState(outState);}/*** Activity被系统杀死后再重建时被调用.* 比如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.* 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.*/Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {param savedInstanceState.getInt(param);Log.i(TAG, onRestoreInstanceState called. get param: param);super.onRestoreInstanceState(savedInstanceState);}
}大家注意到除了几个常见的方法外我们还加入了onWindowFocusChanged、onSaveInstanceState、onRestoreInstanceState方法 1.onWindowFocusChanged方法在Activity窗体获得或失去焦点时被调用比如创建时首次呈如今用户面前当前Activity被其它Activity覆盖当前Activity转到其它Activity或按Home键回到主屏自身退居后台用户退出当前Activity。以上几种情况都会调用onWindowFocusChanged而且当Activity被创建时是在onResume之后被调用当Activity被覆盖或者退居后台或者当前Activity退出时它是在onPause之后被调用如图所看到的 这种方法在某种场合下还是非常实用的比如程序启动时想要获取视特定视图组件的尺寸大小在onCreate中可能无法取到由于窗体Window对象还没创建完毕这个时候我们就须要在onWindowFocusChanged里获取假设大家已经看过我写的Android动画之Frame Animation这篇文章就会知道当时试图在onCreate里载入frame动画失败的原因就是由于窗体Window对象没有初始化完毕所以最后我将载入动画的代码放到了onWindowFocusChanged中问题迎刃而解。只是大家或许会有疑惑为什么我在代码里将它凝视掉了由于对当前Activity每个操作都有它的运行log我操心这会影响到整个流程的清晰度所以将它注掉大家仅仅要了解它应用的场合和运行的顺序就能够了。 2.onSaveInstanceState(1)在Activity被覆盖或退居后台之后系统资源不足将其杀死此方法会被调用(2)在用户改变屏幕方向时此方法会被调用(3)在当前Activity跳转到其它Activity或者按Home键回到主屏自身退居后台时此方法会被调用。第一种情况我们无法保证什么时候发生系统依据资源紧张程度去调度另外一种是屏幕翻转方向时系统先销毁当前的Activity然后再重建一个新的调用此方法时我们能够保存一些暂时数据第三种情况系统调用此方法是为了保存当前窗体各个View组件的状态。onSaveInstanceState的调用顺序是在onPause之前。 3.onRestoreInstanceState(1)在Activity被覆盖或退居后台之后系统资源不足将其杀死然后用户又回到了此Activity此方法会被调用(2)在用户改变屏幕方向时重建的过程中此方法会被调用。我们能够重写此方法以便能够恢复一些暂时数据。onRestoreInstanceState的调用顺序是在onStart之后。 以上着重介绍了三个相对陌生方法之后以下我们就来操作一下这个Activity看看它的生命周期究竟是个什么样的过程 1.启动Activity 在系统调用了onCreate和onStart之后调用了onResume自此Activity进入了执行状态。 2.跳转到其它Activity或按下Home键回到主屏 我们看到此时onSaveInstanceState方法在onPause之前被调用了而且注意退居后台时onPause后onStop相继被调用。 3.从后台回到前台 当从后台会到前台时系统先调用onRestart方法然后调用onStart方法最后调用onResume方法Activity又进入了执行状态。 4.改动TargetActivity在AndroidManifest.xml中的配置将android:theme属性设置为android:style/Theme.Dialog然后再点击LifeCycleActivity中的button跳转行为就变为了TargetActivity覆盖到LifeCycleActivity之上了此时调用的方法为 注意另一种情况就是我们点击button仅仅是按下锁屏键运行的效果也是如上。 我们注意到此时LifeCycleActivity的OnPause方法被调用并没有调用onStop方法由于此时的LifeCycleActivity没有退居后台仅仅是被覆盖或被锁屏onSaveInstanceState会在onPause之前被调用。 5.按回退键使LifeCycleActivity从被覆盖回到前面或者按解锁键解锁屏幕 此时仅仅有onResume方法被调用直接再次进入执行状态。 6.退出 最后onDestory方法被调用标志着LifeCycleActivity的终结。 大家似乎注意到在全部的过程中并没有onRestoreInstanceState的出现这个并不奇怪由于之前我们就说过onRestoreInstanceState仅仅有在杀死不在前台的Activity之后用户回到此Activity或者用户改变屏幕方向的这两个重建过程中被调用。我们要演示第一种情况比較困难我们能够结合另外一种情况演示一下详细过程。顺便也向大家解说一下屏幕方向改变的应对策略。 首先介绍一下关于Activity屏幕方向的相关知识。 我们能够为一个Activity指定一个特定的方向指定之后即使转动屏幕方向显示方向也不会跟着改变 1.指定为竖屏在AndroidManifest.xml中对指定的Activity设置android:screenOrientationportrait或者在onCreate方法中指定 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //竖屏2.指定为横屏在AndroidManifest.xml中对指定的Activity设置android:screenOrientationlandscape或者在onCreate方法中指定 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //横屏为应用中的Activity设置特定的方向是经经常使用到的办法能够为我们省去不少不必要的麻烦。只是我们今天讲的是屏幕方向改变时的生命周期所以我们并不採用固定屏幕方向这样的办法。 以下我们就结合实例解说一下屏幕转换的生命周期我们新建一个Activity命名为OrientationActivity例如以下 package com.scott.lifecycle;import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;public class OrientationActivity extends Activity {private static final String TAG OrientationActivity;private int param 1;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.orientation_portrait);Log.i(TAG, onCreate called.);}Overrideprotected void onStart() {super.onStart();Log.i(TAG, onStart called.);}Overrideprotected void onRestart() {super.onRestart();Log.i(TAG, onRestart called.);}Overrideprotected void onResume() {super.onResume();Log.i(TAG, onResume called.);}Overrideprotected void onPause() {super.onPause();Log.i(TAG, onPause called.);}Overrideprotected void onStop() {super.onStop();Log.i(TAG, onStop called.);}Overrideprotected void onDestroy() {super.onDestroy();Log.i(TAG, onDestory called.);}Overrideprotected void onSaveInstanceState(Bundle outState) {outState.putInt(param, param);Log.i(TAG, onSaveInstanceState called. put param: param);super.onSaveInstanceState(outState);}Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {param savedInstanceState.getInt(param);Log.i(TAG, onRestoreInstanceState called. get param: param);super.onRestoreInstanceState(savedInstanceState);}//当指定了android:configChangesorientation后,方向改变时onConfigurationChanged被调用Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);Log.i(TAG, onConfigurationChanged called.);switch (newConfig.orientation) {case Configuration.ORIENTATION_PORTRAIT:setContentView(R.layout.orientation_portrait);break;case Configuration.ORIENTATION_LANDSCAPE:setContentView(R.layout.orientation_landscape);break;}}
}首先我们须要进入“Settings-Display”中将“Auto-rotate Screen”一项选中表明能够自己主动依据方向旋转屏幕然后我们就能够測试流程了当我们旋转屏幕时我们发现系统会先将当前Activity销毁然后重建一个新的 系统先是调用onSaveInstanceState方法我们保存了一个暂时參数到Bundle对象里面然后当Activity重建之后我们又成功的取出了这个參数。 为了避免这样销毁重建的过程我们须要在AndroidMainfest.xml中对OrientationActivity相应的activity配置android:configChangesorientation然后我们再測试一下我试着做了四次的旋转打印例如以下 能够看到每次旋转方向时仅仅有onConfigurationChanged方法被调用没有了销毁重建的过程。 下面是须要注意的几点 1.假设activity配置了android:screenOrientation属性则会使android:configChangesorientation失效。 2.模拟器与真机区别非常大模拟器中假设不配置android:configChanges属性或配置值为orientation切到横屏运行一次销毁-重建切到竖屏运行两次。真机均为一次。模拟器中假设配置android:configChangesorientation|keyboardHidden假设是Android4.0则是orientation|keyboardHidden|screenSize切竖屏运行一次onConfigurationChanged切横屏运行两次。真机均为一次。 Activity的生命周期与程序的健壮性有着密不可分的关系希望朋友们可以认真体会、熟练应用。 转载于:https://www.cnblogs.com/zfyouxi/p/4265377.html