Android(安卓)activity 详解一:activity的生命周期
一、概述:
Activity是android的四大组件之一,是用户接口程序,它会提供给用户一个交互式的接口功能。它是 android 应用程序的基本功能单元,其实Android中的Activity运行机制跟servlet有些相似之处,Android系统相当于servlet容器,Activity相当于一个servlet,我们的Activity处在这个容器中,一切创建实例、初始化、销毁实例等过程都是容器来调用的 ,activity 本身是没有界面的。所以activity类创建了一个窗口,开发人员可以通过setContentView(View)接口把UI放到activity创建的窗口上。
二、生命周期
1、onCreate: 在这里创建界面,做一些数据的初始化操作
2、onStart: 用户可见但不可交互的状态
3、onResume: 可与用户交互的状态(Activity的栈系统通过栈的方式管理Activity)
4、onPause:用户可见不可交互状态,系统会停止动画等消耗CPU的事情,应该在这里保存你的一些数据,因为这个时候你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在onResume里读出来。
5、onStop:不可见,被下一个Activity覆盖
6、onDestroy:这是Activity被kill前最后一个被调用方法了,可能是其他类调用finish方法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有一个Progress Dialog在线程中运行,请在onDestroy里把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛异常。onPause,onstop, onDestroy,三种状态下 activity都有可能被系统kill 掉。
package com.example.activity;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity { private static final String TAG = "LifeCycleActivity"; private int param = 1; private Button button; //activity创建时被调用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "onCreate called."); setContentView(R.layout.activity_main); button = (Button) this.findViewById(R.id.button1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(MainActivity.this,TargetActivity.class); startActivity(intent); } }); } //activity创建时或者后台重新回到前台时被调用 @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Log.i(TAG, "onStart called."); } //activity从后台重新回到前台时被调用 @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); Log.i(TAG, "onRestart called."); } //Activity创建或者从被覆盖、后台重新回到前台时被调用 @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.i(TAG, "onResume called."); } //Activity被覆盖到下面或者锁屏时被调用 @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); Log.i(TAG, "onPause called."); //有可能在执行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据 } //退出当前Activity或者跳转到新Activity时被调用 @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Log.i(TAG, "onStop called."); } //退出当前Activity时被调用,调用之后Activity就结束了 @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.i(TAG, "onDestroy called."); } //Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后 @Override public void onWindowFocusChanged(boolean hasFocus) { // TODO Auto-generated method stub super.onWindowFocusChanged(hasFocus); Log.i(TAG, "onWindowFocusChanged called."); } /** * Activity被系统杀死时被调用. * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死. * 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态. * 在onPause之前被调用. */ @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub Log.i(TAG, "onSaveInstanceState called."); super.onSaveInstanceState(outState); } /** * Activity被系统杀死后再重建时被调用. * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity. * 这两种情况下onRestoreInstanceState都会被调用,在onStart之后. */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { // TODO Auto-generated method stub Log.i(TAG, "onRestoreInstanceState called."); super.onRestoreInstanceState(savedInstanceState); }}
过程:
1、启动Activity,首先会调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
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。
8、onWindowFocusChanged方法:在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前Activity。以上几种情况都会调用onWindowFocusChanged,并且当Activity被创建时是在onResume之后被调用,当Activity被覆盖或者退居后台或者当前Activity退出时,它是在onPause之后被调用,如图所示:
这个方法在某种场合下还是很有用的,例如程序启动时想要获取视特定视图组件的尺寸大小,在onCreate中可能无法取到,因为窗口Window对象还没创建完成,这个时候我们就需要在onWindowFocusChanged里获取。
9、onSaveInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,此方法会被调用;(2)在用户改变屏幕方向时,此方法会被调用;(3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。第一种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新的,调用此方法时,我们可以保存一些临时数据;第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。onSaveInstanceState的调用顺序是在onPause之前。
10、onRestoreInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此Activity,此方法会被调用;(2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。onRestoreInstanceState的调用顺序是在onStart之后
三、横竖屏切换
package com.example.activity;import android.app.Activity;import android.content.res.Configuration;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private int param = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.orientation_portrait); Log.i(TAG, "onCreate called."); } @Override protected void onStart() { super.onStart(); Log.i(TAG, "onStart called."); } @Override protected void onRestart() { super.onRestart(); Log.i(TAG, "onRestart called."); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume called."); } @Override protected void onPause() { super.onPause(); Log.i(TAG, "onPause called."); } @Override protected void onStop() { super.onStop(); Log.i(TAG, "onStop called."); } @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestory called."); } @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("param", param); Log.i(TAG, "onSaveInstanceState called. put param: " + param); super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { param = savedInstanceState.getInt("param"); Log.i(TAG, "onRestoreInstanceState called. get param: " + param); super.onRestoreInstanceState(savedInstanceState); } //当指定了android:configChanges="orientation"后,方向改变时onConfigurationChanged被调用 @Override public 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; } }}
一.无设置configChanges属性
1、旋转屏幕
旋转屏幕时,系统会先将当前Activity销毁,然后重建一个新的,系统先是调用onSaveInstanceState方法,我们保存了一个临时参数到Bundle对象里面,然后当Activity重建之后我们又成功的取出了这个参数。
如果要避免重新创建,我们需要在AndroidMainfest.xml中对OrientationActivity对应的配置android:configChanges=”orientation”;
* 二.在AndroidManifest里添加configChanges的orientation属性
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.screen" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="orientation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
做了四次旋转,可以看到,每次旋转方向时,只有onConfigurationChanged方法被调用,没有了销毁重建的过程。
以下是需要注意的几点:
1.如果配置了android:screenOrientation属性,android:configChanges=”orientation”失效。
2.模拟器与真机差别很大:模拟器中如果不配android:configChanges属性或配置值为orientation,切到横屏执行一次销毁->重建,切到竖屏执行两次。真机均为一次。模拟器中如果配置android:configChanges=”orientation|keyboardHidden”(如果是Android4.0,则是”orientation|keyboardHidden|screenSize”),切竖屏执行一次onConfigurationChanged,切横屏执行两次。真机均为一次。
Activity的生命周期与程序的健壮性有着密不可分的关系,希望朋友们能够认真体会、熟练应用。
更多相关文章
- 简单明了的分析Android触摸事件,看完再也不纠结了
- Android的MediaPlayer架构介绍
- 初学者---Android(安卓)Fragment之间数据传递的三种方式
- Android(安卓)中webview与原生Java的 交互以及网页JS 与原生的交
- Android(安卓)init.rc文件解析过程分析
- Android的线程
- Webview实现Android和JS通信
- 【转】Android(安卓)技术-- 图形系统详解
- afinal - afinal 是一个android的 orm 和 ioc 框架。通过afinal