Android开发之Activity的生命周期

路漫漫其修远兮,吾将上下而求索。---屈原《离骚》

可能很多人会感觉Activity很简单,但是经历了半年的android开发,我发现我对Activity的的理解还是比较浅显的,其实Activity并没有我们想象的那么简单今天花了一个下午学习了Activity的生命周期,为以后忘记后迅速回顾,做准备。

一、首先看下官网给出activity的生命周期图

我们可以从图中分析它的执行过程:

1.启动Activity:系统会首先调用onCreate方法,然后调用onStart方法,最后调用onResume()方法。此时Activity进入运行状态

2.当前Activity被其他Activity覆盖或处于锁屏状态:系统会调用onPause方法,然后调用onStop方法,此时Activity处于停滞状态。

3.当前Activity由覆盖状态回到前台或解锁屏:系统会调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。

4.当前Activity跳转到新的Activity界面或Home键回到主屏,退到后台:系统会先调用onPause方法,然后调用onStop方法进入停滞状态

5.用户后退回到此Activity:系统会先调用onRestart()方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态

6.当前Activity处于被覆盖状态或者后台不可见状态,即第二和第四步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。

7.用户退出当前Activity:系统会调用onPause方法,然后调用onStop方法最后调用onDestroy方法,结束当前Activity

以上的Activity方法的生命周期是很简单的,但是任何简单的东西,只有我们通过实例验证才能理解的更加透彻,记忆更加深刻,

二、实例分析

实例代码:

package com.example.activitypractice;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

     private static final String TAG = "MainActivity";

     private Button btn_jump;
     private String saveData= "存放的数据" ;

     //Activity创建时调用
     @Override
     protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           setContentView(R.layout. activity_main);

            btn_jump=(Button) findViewById(R.id. btn_jump);
            btn_jump.setOnClickListener( new OnClickListener() {

                 public void onClick(View v) {
                     Intent intent= new Intent(MainActivity.this,JumpToActivity.class );
                     startActivity(intent);
                }
           });

           Log. i(TAG,"执行了onCreate方法" );
     }

     //Activity创建或者从后台重新回到前台时被调用
     @Override
     protected void onStart() {
            super.onStart();
           Log. i(TAG,"执行了onStart方法" );
     }

     //Activity从后台重新回到前台时被调用
     @Override
     protected void onRestart() {
            super.onRestart();
           Log. i(TAG,"执行了onRestart方法" );
     }

     //Activity创建或者从被覆盖、后台重新回到前台时被调用
     @Override
     protected void onResume() {
            super.onResume();
           Log. i(TAG,"执行了onResume方法" );
     }

     //Activity被覆盖到下面或者锁屏时被调用
     @Override
     protected void onPause() {
            super.onPause();
           Log. i(TAG,"执行了onPause方法" );
     }

     //退出当前Activity或者跳转到新Activity时被调用
     @Override
     protected void onStop() {
            super.onStop();
           Log. i(TAG,"执行了onStop方法" );
     }

     //退出当前Activity时被调用,调用之后Activity就结束了
     @Override
     protected void onDestroy() {
            super.onDestroy();
           Log. i(TAG,"执行了onDestroy方法" );
     }

     //Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后
   /* @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Log.i(TAG, "onWindowFocusChanged called.");
    }  */

     /**
     * Activity被系统杀死时被调用.
     * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.
     * 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.
     * 在onPause之前被调用.
     */
     @Override
     protected void onSaveInstanceState(Bundle outState) {
           outState.putString( "key", saveData);
           Log. i(TAG, "onSaveInstanceState called.put saveData: " + saveData );
            super.onSaveInstanceState(outState);
     }

     /**
     * Activity被系统杀死后再重建时被调用.
     * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.
     * 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.
     */
     @Override
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
           String getData = savedInstanceState.getString( "key");
           Log. i(TAG, "onRestoreInstacedState called.getData: "+getData);
            super.onRestoreInstanceState(savedInstanceState);

     }
}

在上面的例子中我们可以看到还有三个不是特别常见的方法,onWindowFocusChanged、onSaveInstanceState、onRestoreInstanceState方法这三个方法我们用的比较少下面也来说说它们的用法:

(1)onWindowFocusChanaged方法

在Activity窗口获得或失去焦点时调用,例如创建时首次展示在用户面前、当Activity被其它Activity所覆盖、Activity退到后台、用户退出当前Activity,这几种条件都会调用onWindowFocusChanaged,并且当Activity被创建时是在onResume之后被调用,当Activity被覆盖或者退到后台或当前Activity退出时它是在onPause之后被调用的,如下图Activity启动之后被其它的activity覆盖(点击我们的跳转按钮)打印的日志

这个方法在很多场合下还是很有用的,例如程序启动时想要获取组件的尺寸大小,在onCreate中是无法取到的因为Window对象还没有创建完,这时候我们就需要在onWindwosFocusChanaged里获取,这也是我们常用的方法。

(2)onSaveInstanceState:

1.在Activity被覆盖或者退到后台之后,系统资源不足,将其杀死,此方法会被调用;

2.在用户改变屏幕方向时此方法会被调用;

3.在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退到后台时,此方法会被调用。

第一种情况我们无法保证什么时候发生,系统根据资源的紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前Activity,然后再重建一个新的,调用此方法时,我们可以保存一些临时数据,例如:当竖屏时加载一个进度条,切换到横屏时如果不保存当前加载到多少横屏时会重0开始,保存后就可以继续加载,第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。onSaveInstanceState的调用顺序是在onPause之后,如下图是在跳转到其它的Activity所执行的方法

我们从图中可以看出onSaveInstanceState方法是在onPause方法中执行的

(3)onRestoreInstanceState

1.在Activity被覆盖或是退居后台之后,系统资源不足将其杀死,然后又回到了此Activity,此方法会被调用

2.在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便恢复一些临时数据。onRestoreInstanceState的调用顺序是在onStart方法之后。

之后我们来结合上面的例子来一 一看看Activity的生命周期在各种的情况下的变化

1.启动Activity:

启动Activity:系统会首先调用onCreate方法,然后调用onStart方法,最后调用onResume()方法。此时Activity进入运行状态

2.在1跳转到其他的Activity,或按Home键

系统会先调用onPause方法,然后调用 onSaveInstanceState方法,然后调用onStop方法进入停滞状态

3.从后台回到前台

系统会先调用onRestart方法,然后调用onStart方法,然后调用onResume方法

4.修改在AndroidMainfest.xml中的配置,将android:theme属性设置为@android:style/Theme.Dialog,然后再点击跳转按钮,然后JumpToActivity覆盖到LifeCycleActivity之上了,

此时调用的方法为:onPause和onSaveInstanceState,我们注意到,此时MainActivity的onPause方法被调用,并没有执行onStop方法,因为此时的MainActivity没有退居到后台只是被覆盖或被锁屏;onSaveInstanceState会在onPause之后被调用

5.在4的基础上按回退键MainActivity从被覆盖回到前面

此时执行onResume方法

6.退出

系统调用onPause、onStop、onDestroy方法。

不知道大家有没有发现在上面的所有的日志中并没有执行onRestoreInstanceState方法,为什么没有执行它呢没有满足它执行的条件,从上面onRestoreInstanceState执行的条件我们发现第一种是不可预测的,但是第二种(即改变屏幕方向)的话我们可以模拟的

三、Activity屏幕方向的知识

我们可以为一个Activity指定一个特定的方向,指定之后即使转动屏幕方向,显示方向也不会跟着转动

1.指定为竖屏:在AndroidManifest.xml文件中对指定的Activity设置android:screenOrientation:="portrait",

或者在onCreate方法中指定代码为:

setRequestOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);就指定为了竖屏

2.指定为横屏:在AndroidManifest.xml文件中对指定的Activity设置android:screenOrientation:="landscape",

或者在onCreate方法中指定代码为:

setRequestOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);就指定为了竖屏

在开发应用的过程中,为应用中的Activity设置特定的方向是经常用到的方法,可以为我们省去很多麻烦,但是我为了让onRestoreInstanceState方法执行采用的是不固定屏幕的显示方向我们对上面的代码稍作修改加上onConfigurationChanged方法

现在源码如下:

package com.example.activitypractice;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

     private static final String TAG = "MainActivity";

     private Button btn_jump;
     private String saveData= "存放的数据" ;

     //Activity创建时调用
     @Override
     protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           setContentView(R.layout. activity_main);

            btn_jump=(Button) findViewById(R.id. btn_jump);
            btn_jump.setOnClickListener( new OnClickListener() {

                 public void onClick(View v) {
                     Intent intent= new Intent(MainActivity.this,JumpToActivity.class );
                     startActivity(intent);
                }
           });

           Log. i(TAG,"执行了onCreate方法" );
     }

     //Activity创建或者从后台重新回到前台时被调用
     @Override
     protected void onStart() {
            super.onStart();
           Log. i(TAG,"执行了onStart方法" );
     }

     //Activity从后台重新回到前台时被调用
     @Override
     protected void onRestart() {
            super.onRestart();
           Log. i(TAG,"执行了onRestart方法" );
     }

     //Activity创建或者从被覆盖、后台重新回到前台时被调用
     @Override
     protected void onResume() {
            super.onResume();
           Log. i(TAG,"执行了onResume方法" );
     }

     //Activity被覆盖到下面或者锁屏时被调用
     @Override
     protected void onPause() {
            super.onPause();
           Log. i(TAG,"执行了onPause方法" );
     }

     //退出当前Activity或者跳转到新Activity时被调用
     @Override
     protected void onStop() {
            super.onStop();
           Log. i(TAG,"执行了onStop方法" );
     }

     //退出当前Activity时被调用,调用之后Activity就结束了
     @Override
     protected void onDestroy() {
            super.onDestroy();
           Log. i(TAG,"执行了onDestroy方法" );
     }

     /**
     * Activity被系统杀死时被调用.
     * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.
     * 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.
     * 在onPause之前被调用.
     */
     @Override
     protected void onSaveInstanceState(Bundle outState) {
           outState.putString( "key", saveData);
           Log. i(TAG, "onSaveInstanceState called.put saveData: " + saveData );
            super.onSaveInstanceState(outState);
     }

     /**
     * Activity被系统杀死后再重建时被调用.
     * 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.
     * 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.
     */
     @Override
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
           String getData = savedInstanceState.getString( "key");
           Log. i(TAG, "onRestoreInstacedState called.getData: "+getData);
            super.onRestoreInstanceState(savedInstanceState);

     }

     //当指定了android:configChanges="orientation"后,方向改变时onConfigurationChanged被调用,并且activity不再销毁重建
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            switch (newConfig. orientation) {
            case Configuration. ORIENTATION_PORTRAIT://竖屏
                Log. i(TAG,"竖屏" );
                setContentView(R.layout. portrait);
                 break;
            case Configuration. ORIENTATION_LANDSCAPE://横屏
                Log. i(TAG,"横屏" );
                setContentView(R.layout. landscap);
            default:
                 break;
           }
     }
}

需要注意的是我们必须在手机上设置(注意:要在设置中设置自动旋转屏幕我用的三星的测试机是在设定-->我的设备-->显示
 在"显示"里有"自动旋转屏幕"选项)自动旋转屏幕才可以

然后当我们旋转屏幕时,我们会看到Activity首先会销毁然后重建,系统会调用onSaveInstanceState方法并在Bundle对象中保存了一个临时的数据,当Activity销毁后再重建时调用onRestoreInstancedState方法我们从中可以把保存的数据取出来日志如下:

但是Activity销毁后再重建,这有时候并不是我们想要的,那么我们应该怎样避免这种情况呢?这是我们应该在清单文件中对应的Activity中配置android:configChanges="orientation"然后我们再旋转屏幕

每次在旋转的时候都调用了onConfigurationChanged方法,并且Activity没有了销毁重建的过程

在上面的配置过程中我们需要注意几点:

1.如果在Activity中配置了android:screenOrientation属性,则会使android:configChanges="orientation"失效。

2.在配置android:configChanges时需要注意:如果是Android 4.0,则是"orientation|keyboardHidden|screenSize",如果是

4.0之前的版本android:configChanges="orientation|keyboardHidden"

关于android:configChanges配置时需注意的事项见此链接

时间: 2024-10-22 01:53:37

Android开发之Activity的生命周期的相关文章

android开发之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

背景:之前有过两篇写activity的博客 android之activity的生命周期详解:详细介绍了activity的整个生命周期.各状态间的转换和返回桌面时保存activity的状态 android之activity中onSaveInstanceState和onRestoreInstanceState的触发时机:介绍了activity中这两个方法的触发时机和作用 本篇博客会牵扯到里面的内容,如果你都有所了解可以直接往下看,如果不了解可以进去回忆下. 问题:在做应用的退出对话框时,发现如果对话

Android开发之Activity的创建跳转及传值

在Android系统的江湖中有四大组件:活动(Activity), 服务(Service), 广播接收器(Broadcast Reciver)和内容提供者(Content Provider).今天所介绍的就是Android开发中的四大组件之一:Activity,其他那三大组件以后再进行介绍.说道Android中的Activity,如果你做过iOS开发的话,Activity类似于iOS中的ViewController(视图控制器).在应用中能看到的东西都是放在活动中的.活动是安卓开发比较重要的东西

Android开发之Activity和Fragment生命周期对比图

一.Activity 生命周期 二.Fragment 生命周期 三.对比图 四.测试代码 [java] view plaincopy package com.goso.testapp; import android.app.Activity; import android.app.ListFragment; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import a

Liferay7 BPM门户开发之17: Portlet 生命周期

Portlet 生命周期 init() =〉 render() =〉 processAction() =〉 processEvent() =〉 serveResource() =〉destroy() init() 在Liferay容器部署portlet时,启动portlet实例化 init有两个写法: public void init() throws PortletException public void init(PortletConfig config) throws PortletEx

Android开发之Activity(cho1)篇

一.Activity判断网络是否连通: 首先创建一个Andorid Project项目,然后添加一个on1类,Layout一个button控件和Textview控件. values有一个Color.xml文件和string.xml文件(注:Color.xml文件可以网上找) Color.xml文件: string.xml文件: MainActivity.java文件: 通过findViewById获取R资源文件中的控件,并且通过setOnClickListener方法将on1加入监听管理. pr

Android开发之Activity的启动模式

黑发不知勤学早,白首方悔读书迟.--<劝学> 今天花了整个下午+晚上的的时间学习了Activity的启动模式,本来以为这个知识点很简单,但是在学习的过程中发现,Activity的启动模式并没有自己想象的那么简单,下面我们一起来看看这Activity的四种启动模式吧,如有疑问欢迎留言,如有谬误欢迎大家批评指正,谢谢 Activity的启动模式共有四种 1.standard 2.singleTop 3.singleTask 4.singleInstance 如图所示: LaunchMode在多个A

Android学习笔记-Activity的生命周期

界面activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="matc

Android Studio 之 Activity 的生命周期

翻转屏幕,会重新加载Activity package com.example.activitylivecycle; import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { //定义 TAG 方便自己容易查找日志 //翻转屏幕,Activity 会重

Android开发之Activity之间的数据传递

通过putExtra设置值,通过getExtra获取值 putExtra需要设置键值对,getExtra通过对应的键获取传递的值(直接在getExtra之间加上想获取的值类型) 1.在一个Activity通过startActivityForResult()开启另一个Activity 2.该方法通常接收两个参数,第一个是Intent对象,第二个是requestCode 3.在第一个Activity中重写onActivityResult方法,通过switch判断传过来的requestCode(哪个A