从新认识Android Activity的生命周期

1、基础
html

 看了官方文档以后,本身领悟过来接着翻译的,因为第一次的缘由,技术水品乜有跟上,还请你们将就将就。若是你有更好的建议的,但愿你能够提出,若是你以为哪里写的很差的,恳请留下你的指导意见,谢谢。java

1、基础android

   1.1本身建立的activity必需要继承类Activity(或其子类)。在activity里,为了实现activity各类状态的切换,你必须实现指定的回调方法。如下是最为重要的两个回调方法数据库

      onCreate():网络

   这是必须实现的回调方法,启动一个 activity时会首先调用此方法。所以,在onCreate()的方法体里,你应该初始化该activity必要的控件。值得注意的是,在这里你必须调用setContentViewView view)方法去呈现用户的界面。app

      onPause()ide

   在用户将要离开activity时调用此方法(指的是此时activity处于半透明状态且没有获取用户的焦点)。一般在这样的状态下,你须要处理用户数据的提交、动画处理等操做。布局

   1.2销毁activity测试

   你能够调用finish()方法去销毁一个activity。一样得,你能够调用finishActivity()方法去销毁一个你刚刚启动的activity动画

tips

在多数状况下,你是不须要显式地调用finish…()方法去销毁一个activity。在将要讨论到的activity生命周期里,你能够知道,Android系统会为你管理activity的生命周期,因此你并不须要显式销毁activity(即调用finish类方法)。显式地调用finish类方法,会对用户的体验产生不利的影响,除非你确实是不但愿用户返回到此activity(界面),才去显式调用finish类方法。



2、认识activity的生命周期

21

  Activity的生命周期对它的任务、backstack和与此有关联的activity有着直接的影响。所以想开发出一个健壮的有弹性的Android程序,你须要学会如何去管理activity的生命周期(即调用各类回调方法)。

  activity的生命周期主要包含一些三种状态:

1)运行态(Resumedstate

   此时Activity程序显示在屏幕前台,而且具备焦点,能够与用户的操做进行交互,如向用户提供信息、捕获用户单击按钮的事件并作处理。

2)暂停态(PausedState

此时Activity程序失去了焦点,并被其余处于运行态的otherActivity取代在屏幕显示,但otherActivity程序并无覆盖整个屏幕或者具备半透明的效果—此状态即为暂停态。处于暂停态的Activity仍然对用户可见,而且是彻底存活的(此时Activity对象存留在内存里,保留着全部状态与成员信息并保持与窗口管理器的链接)。若是系统处于内存不足的状况下,会杀死这个Activity

3)中止态(StoppedState

Activity彻底被另外一个otherActivity覆盖时(此时otherActivity显示在屏幕前台),则处于中止态。处于停滞态的Activity依然是存活的(此时Activity对象依然存留在内存里,保留着全部的状态和与成员信息,但没有与窗口管理器保持链接),并且它对用户是不可见的,若是其余地方须要内存,系统会销毁这个Activity



   处于暂停态(PausedState)或者中止态(Stopped State)Activity,系统能够经过调用finish()方法或者直接终止它的进程来销毁此Activity(从内存中清楚此Activity对象)。被finish()或者销毁的Activity再从新打开时,是须要再次初始化此Activity的。


22

当一个Activity从一种状态转到另外一种状态时,会经过调用回调方法来通知这种变化。这些回调方法都是能够重写的,你能够根据程序的的须要来选择重写对应的回调方法。如下列出了Activity生命周期里的基本回调方法:

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The activity is being created.
    }
    @Override
    protected void onStart() {
        super.onStart();
        // The activity is about to become visible.
    }
    @Override
    protected void onResume() {
        super.onResume();
        // The activity has become visible (it is now "resumed").
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Another activity is taking focus (this activity is about to be "paused").
    }
    @Override
    protected void onStop() {
        super.onStop();
        // The activity is no longer visible (it is now "stopped")
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
    }
}

   笔记:在方法体里,必须先调用父类对应的实现方法super.Xxx(),再执行其余的操做(如上面代码所示)。为了习惯,下面也提供一些代码来测试一些这些方法的使用,在博客的最后面。


   总的来讲,这些回调方法定义了Activity整个生命周期。在生命周期里经过重写这些回调方法,,你能够监控如下下三个嵌套的方法循环。


完整存活的时间:

Activity的完整存活的时间是自第一次调用onCreate()开始,直至调用onDestroy()为止。ActivityonCreate()中设置全部“全局”状态以完成初始化,而在onDestroy()中释放全部系统资源。例如,若是Activity有一个线程在后台运行从网络下载数据,它会在onCreate()建立线程,而在 onDestroy()销毁线程。


可见状态的时间:

Activity的可见状态是自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户能够在屏幕上看到Activity,尽管它也许并非位于前台或者也不与用户进行交互。在这两个方法之间,咱们能够保留用来向用户显示这个Activity所需的资源。例如,当用户再也不看见咱们显示的内容时,咱们能够在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化,而在onStop()中来注消。onStart() onStop() 方法能够随着应用程序是否为用户可见而被屡次调用。


显示在前台的时间:

  Activity的前台显示是自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。Activity会常常在暂停和恢复之间进行状态转换——例如当设备转入休眠状态或者有新的Activity启动时,将调用onPause() 方法。当Activity得到结果或者接收到新的Intent时会调用onResume() 方法。


2.3

下图显示了这三个循环之间的状态转换(其中写在长方形里的是你能够用来重写并实现对应操做的方法)。










































一样的,如下面的表格来描述生命周期里的回调方法,并包含了更加详细的信息。

方法

描述

是否能够终止

下一个方法

onCreate()

Activity程序启动以后会首先调用此方法。在这个方法体里,你须要完成全部的基础配置——建立视图,链接数据库并将数据绑定到list列表中,等等。这个方法会传递一个保存了此Activity上一状态信息的Bundle对象。紧随其后的方法老是onStart().

不能够

onStart()


onRestart()

处于中止态的Activity调用此方法,可让此Activity从新显示在前台。

紧随其后的方法老是onStart()

不能够

onStart()

onStart()

在此Activity可见(显示在前台)以前调用。

若是接着是显示在前台,紧随其后的方法是onResume()若是接下来此Activity被隐藏了,则紧随其后的方法是onStop()

不能够

onResume()

onStop()


onResume()

在与用户进行交互以前调用此方法,这一时刻Activity位于activity栈的栈顶,在等待用户的操做(输入数据或点击按钮等)。紧随其后的方法是onPause().

不能够

onPause()

onPause()

当启动其余activity时调用此方法。在这个方法体里,一般用于提交未保存的数据、中止动画/视频和处理其余占用CPU资源的程序,等等。同时在这个方法体里处理的都是一些迅速快捷的操做,由于下一个activity会在onPause()方法执行完以后才能够在前台显示

若是此Activity从新回到前台显示,则紧随其后的方法是onResume();若是此Activity变得不可见了,则紧随其后的方法是onStop()

能够

onResume()

onStop()

onStop()

Activity不可见时调用此方法。这个方法的调用时刻是在Activity须要销毁或者被其余otherActivity取代且覆盖此Activity在前台显示时调用。

若是此Activity从新显示在前台,紧随其后的方法是onRestart();若是此Activity须要被销毁,紧随其后的方法是onDestroy()

能够

onRestart()

onDestroy()

onDestroy()

Activity被销毁时调用此方法。这是Activity生命周期里最后调用的一个方法。这个方法的调用能够发生在activity调用了finish()方法以后,或者是系统为了节省空间而销毁了此Activity的实例。你可使用isFinishing()方法来区分这两种状况。

能够

——


   “是否能够终止”是指系统是否能够在此方法执行完后直接销毁该Activity的实例(没有再去执行此Activity内的其余代码)。如上表所示,onPause(),onStop(),onDestroy()三个方法是能够终止的。同时从状态图(上图)中能够知道onPause()方法是这三个方法中第一个调用的,自一个Activity建立开始,直到此Activity终止或销毁,onPause()是最后一个保证会被调用的方法(如在突发状况下系统回收内存,onStop()onDestroy()就不会被调用)。所以,你应该在onPause()方法里保存一些关键的数据(如用户编辑的内容),所谓“关键“就是让你有选择地去保存一些重要的数据,由于onPause()方法执行时间过长,会延迟下一状态的切换,进而影响了用户的体验。

   附:在上表注明不能够被终止的方法也可能会被系统终止,不过这一状况只会在一些极端的状况下发生。


3、保存Activity的状态信息

   在前文提到过,处于暂停态的和中止态的Activity,其对应的状态的状态与成员信息依然保留在内存里。那么这些信息又是如何保存的??咱们又应该如何去利用这些信息??

   在暂停状态下的activity,因其activity信息完整保存在内存里且保持与窗口管理器的链接,因此能够直接调用onRestart()方法还原activity

用户常常会使用返回按钮返回上一个界面(Activity),用户固然是但愿上一个界面(Activity)和他原来看到或编辑的同样,在这种状况下你就须要使用以前已经保存好的状态信息和成员变量来还原上一个Activity。若要保存一个Activity的状态信息和成员变量,则须要实现回调方法onSaveInstanceState()

   onSaveInstanceState()会在执行onStoped()方法以前调用,这个方法有一个参数Bundle,能够以“名称-值”的形式保存activity的信息(如使用putString(),putInt()方法)。接着在须要还原activity时,系统会调用onCreat()或者OnRestoreInstanceState()这两个方法都传入一个以保存了activity信息的Bundle对象,经过提取Bundle对象的信息来恢复activity。若是没有信息须要保存到Bundle对象,那传递给这两个方法的将是空的Bundle对象(刚开始初始化一个activity时其实就是这种状况)。以下图所示:

   其实,即便你没有实现回调方法onSaveInstanceState()系统也会执行默认的onSaveInstanceState()值得注意的是,系统会为每一个View组件执行相对应的onSaveInstanceState(),这可使每个组件保存本身相对应的信息。在Android里,几乎全部的控件都实现了这个方法,所以在界面产生的可见变化都会自动保存下来,也就能够还原activity。举个例子:在EditText输入的内容或者CheckBox的选择,都会自动保存下来。而你所须要作的就是为须要保存信息的控件提供一个id(在XML文件里的属性android:id,若是你没有为控件提供id,那系统是不会自动保存这些信息的。

下面给出一些例子参考一下onSaveInstanceState()OnRestoreInstanceState()方法的使用:


@Override
    protected void OnSaveInstanceState(Bundle outState)
    {
        outState.PutString("myString", "HelloXamarin.Android OnSaveInstanceState");
        outState.PutBoolean("myBool", true);
        base.OnSaveInstanceState(outState);
    }
    @Override
    protected void OnRestoreInstanceState(Bundle savedState)
    {
        base.OnRestoreSaveInstanceState(savedState);
        var myString =savedState.GetString(amyStringa);
        var myBool =GetBoolean(amyBoola);
    }

   附:若是须要强制控件不保存对应的信息,能够在布局文件设置android:saveEnabled = false”,或者使用控件对象的setSaveEnabled()方法。


   尽管系统默认执行onSaveInstanceState()保存对应控件的信息,有时候你须要实现这个方法去保存一些额外的变量。例如:你须要去保存一些在这个activity生命周期里会改变的变量(指控件信息以外的变量),这些会改变的变量系统是默认不保存的。

   须要注意的是:onSaveInstanceState()方法不保证必定会被调用,因此在这个方法里你只应该保存一些临时变量(如UI的状态),而不要去保存一些须要持久化的数据。相反,你应该在onPaused()方法里保存须要持久化的数据(例如保存到数据库里的数据)。

tips

     Android系统上Back按钮和Home按钮的区别,尽管他们均可以导航到另一个otherActivity(能够是其余程序的),可他们的做用原理是不同的。在界面(Activity)上点击Back按钮,系统会认为这个Activity已完成其对应的实现逻辑,则调用对应的方法销毁此Activity;可当点击Home按钮时,系统会认为这个Activity尚未完成对应的逻辑,则系统并不会销毁这个Activity,而是让其处于中止态(Stopped State.



4、协调各个Activity

   当ActivityA启动ActivityB时,这两个Activity都须要进行状态的切换。当ActivityB建立的时候,ActivityA会切换到暂停态或者中止态(当ActivityA依然可见是切换到暂停态,不可见则切换到中止态)。假设这两个Activity共享某些存储在磁盘的数据,这样颇有必要去知道,在ActivityB建立完成以前,ActivityA都尚未切换到中止态(StopppedState)

   当两个Activity处于源于同一个App,又是一个启动另一个Activity的时候,其生命周期的回调方法是已经定义好的了。一下是这两个Activity状态切换个回调方法的调用顺序。

  1.执行ActivityAonPaused()方法

  2.依次执行ActivityBonCreate(),onStart(),onResume()方法(此时ActivityB显示在前台,得到焦点)。

  3.而后,若是ActivityA变得不可见,则执行ActivityAonStopped()方法。

   根据这些方法调用顺序,能够知道:若是须要在ActivityA保存数据到数据库,接着让ActivityB读取,那么你应该onPaused()方法里执行持久化操做,而不是在onStopped()方法里。



附录:activityLifecycle的代码和运行效果图。

输出:

输出(注意其调用的顺序):

输出:


ActivityA的代码以下:

public class ActivityA extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);
        System.out.println("ActivityA-->onCreate()");
    }
    @Override
    protected void onStart() {
        super.onStart();
        System.out.println("ActivityA-->onStart()");
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        System.out.println("ActivityA-->onRestart()");
    }
    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("ActivityA-->onResume()");
    }
    @Override
    protected void onPause() {
        super.onPause();
        System.out.println("ActivityA-->onPause()");
    }
    @Override
    protected void onStop() {
        super.onStop();
        System.out.println("ActivityA-->onStop()");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.out.println("ActivityA-->onDestroy()");
    }
    public void startDialog(View v) {
        Intent intent = new Intent(ActivityA.this, DialogActivity.class);
        startActivity(intent);
    }
    public void startActivityB(View v) {
        Intent intent = new Intent(ActivityA.this, ActivityB.class);
        startActivity(intent);
    }
                                                                                                                                             
    public void finishActivityA(View v) {
        ActivityA.this.finish();
    }
}
Action


DialogActivity代码以下:

public class DialogActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_dialog);
        System.out.println("DialogActivity-->onStart()");
    }
                                                                                                  
    @Override
    protected void onStart() {
        super.onStart();
        System.out.println("DialogActivity-->onStart()");
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        System.out.println("DialogActivity-->onRestart()");
    }
    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("DialogActivity-->onResume()");
    }
    @Override
    protected void onPause() {
        super.onPause();
        System.out.println("DialogActivity-->onPause()");
    }
    @Override
    protected void onStop() {
        super.onStop();
        System.out.println("DialogActivity-->onStop()");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.out.println("DialogActivity-->onDestroy()");
    }
                                                                                                  
    public void finishDialog(View v) {
        DialogActivity.this.finish();
    }
                                                                                                  
}

其余代码相似,就不一一张贴了。

相关文章
相关标签/搜索