Activity的生命周期函数

时间:2023-03-08 16:32:53

前言:

上一篇文章写了关于Activity生命周期和生命周期状态的介绍,这一篇文章给大家聊聊Activity生命周期函数。

主Activity:

应用程序的入口一般都是桌面应用程序图标,用户点击应用图标打开应用,这是因为应用程序有主Activity,如果没有主Activity,应用程序就不会在桌面中显示。主Activity在AndroidManifest.xml中的声明如下:

XHTML

1
2
3
4
5
6
<activity android:name=".MainActivity" android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

与普通Activity在AndroidManifest.xml声明的区别就是多了<action android:name="android.intent.action.MAIN" />和<category android:name="android.intent.category.LAUNCHER" />。 Activity有这两个声明才能在桌面应用程序列表中找到。

Activity的生命周期方法都会被系统回调,它们的调用时机都是什么呢?在这些方法中你需要做些什么?先看一张图,对照着图来讲解你可能理解的更明白。

Activity的生命周期函数

图片来自google的developer官网。

OnCreat方法:

onCreat方法在Activity生命周期中只会被调用一次,onCreat后Activity进入Created状态。在这个方法中主要做的工作是初始化你这个Activity需要的资源和加载UI。初始化资源一般都是你定义的变量什么的。加载UI一般都是先在xml文件中设置好布局,然后通过setContentView(layout_xml)加载到应用窗口上(可以理解为每一个应用程序的界面最外层都有一个窗口,叫做Window,所有的view都显示在这个窗口上)。实例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
TextView mTextView; // Member variable for text view in the layout
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the user interface layout for this Activity
    // The layout file is defined in the project res/layout/main_activity.xml file
    setContentView(R.layout.main_activity);
    // Initialize member TextView so we can manipulate it later
    mTextView = (TextView) findViewById(R.id.text_message);
}

OnStart方法:

onCreat方法执行完会紧接着调用到onStart方法,onStart方法后Activity进入Started状态。一般这个方法用不着,因为有其他方法可以替代它完成需要做的工作。这个方法调用完View就会变为可见状态,但是不可交互。从刚开始的图能看到onStart方法在整个生命周期中可能会被调用多次,在Activity进入Stoped状态后也可能再次经过onRestart-》onStart方法再次进入Started状态。

OnResume方法:

onStart方法执行完会紧接着调用onResume方法,走完这个方法Activity就会进入Resumed状态,此时的Activity获得了焦点,可见可交互,这个方法在生命周期中可能会多次调用,只要进入可交互状态必然会走这个方法。在进入这个方法时你需要准备好与用户交互的资源,也就是说用户要看的、要点击的UI资源都要能够快速响应用户,比如要准备好音乐播放器,用户点击播放立刻就能听到音乐。

OnPause方法:

在Activity被前台UI部分或者全部遮挡时会走onPause方法,此时Activity失去焦点,不可交互。比如弹出的对话框,或者进入其他Activity界面。在这个方法中你要处理好用户不再需要的资源,比如停止游戏,停止播放器等,并且需要保存用户现在的数据,比如游戏数据(关卡进度),播放数据(播放进度)等,但是不要进行太耗时的操作。google官网给出的建议是:

  • Stop animations or other ongoing actions that could consume CPU.(停止一切消耗CPU的事,动画,线程等)
  • Commit unsaved changes, but only if users expect such changes to be permanently saved when they leave (such as a draft email).(自动保存用户没有提交的数据,比如编辑的邮件草稿。)
  • Release system resources, such as broadcast receivers, handles to sensors (like GPS), or any resources that may affect battery life while your activity is paused and the user does not need them.(当Activity暂停的时候释放占用的系统资源,这些资源是用户不再需要的,比如:广播,GPS,或者其他消耗电量的设备。)

官网的例子如下:

1
2
3
4
5
6
7
8
9
10
11
@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first
    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    if (mCamera != null) {
        mCamera.release()
        mCamera = null;
    }
}

OnStop方法:

当activity的onStop方法被调用后,Activity进入Stoped状态,完全不可见,此时你需要完全释放用户不再需要的资源,尽管之前你调用了onPause方法释放了一部分资源,但是在onPause方法中你不能执行更大、更耗费CPU的方法,在onStop中使可以的。例如把数据保存到数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
protected void onStop() {
    super.onStop();  // Always call the superclass method first
    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
    getContentResolver().update(
            mUri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
            );
}

在Stoped状态Activity在系统资源紧张的时候会直接被系统回收掉而不再调用onDestroy方法,当然这是很极端的时候发生的。

OnDestroy方法:

Activity生命周期的最后一个方法,一般不会再这个方法里做什么事,应为它有可能不会被调用。大部分的清理工作是在onPause和onStop方法中做的,这个方法是完成清理工作的最后机会,一些可能会引起内存泄露的线程应该在这个方法中停掉,Hander的消息也要清理掉。

总结:

我用了两篇文章来给大家聊聊Activity的生命周期和生命周期方法,主要是理解在各个生命周期方法中该做那些事,不该做那些事,这样就能保证UI显示的正确和快速,数据会被保存,该释放的资源会被释放。如果大家有什么问题可以关注下面的公众号给我留言,大家共同讨论。

关注微信公众平台:程序员互动联盟(coder_online),你可以第一时间获取原创技术文章,和(java/C/C++/Android/Windows/Linux)技术大牛做朋友,在线交流编程经验,获取编程基础知识,解决编程问题。程序员互动联盟,开发人员自己的家。

Activity的生命周期函数