上一篇文章写了关于Activity生命周期和生命周期状态的介绍,这一篇文章给大家聊聊Activity生命周期函数。
应用程序的入口一般都是桌面应用程序图标,用户点击应用图标打开应用,这是因为应用程序有主Activity,如果没有主Activity,应用程序就不会在桌面中显示。主Activity在AndroidManifest.xml中的声明如下:
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的生命周期方法都会被系统回调,它们的调用时机都是什么呢?在这些方法中你需要做些什么?先看一张图,对照着图来讲解你可能理解的更明白。
图片来自google的developer官网。
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
)
;
}
|
onCreat方法执行完会紧接着调用到onStart方法,onStart方法后Activity进入Started状态。一般这个方法用不着,因为有其他方法可以替代它完成需要做的工作。这个方法调用完View就会变为可见状态,但是不可交互。从刚开始的图能看到onStart方法在整个生命周期中可能会被调用多次,在Activity进入Stoped状态后也可能再次经过onRestart-》onStart方法再次进入Started状态。
onStart方法执行完会紧接着调用onResume方法,走完这个方法Activity就会进入Resumed状态,此时的Activity获得了焦点,可见可交互,这个方法在生命周期中可能会多次调用,只要进入可交互状态必然会走这个方法。在进入这个方法时你需要准备好与用户交互的资源,也就是说用户要看的、要点击的UI资源都要能够快速响应用户,比如要准备好音乐播放器,用户点击播放立刻就能听到音乐。
在Activity被前台UI部分或者全部遮挡时会走onPause方法,此时Activity失去焦点,不可交互。比如弹出的对话框,或者进入其他Activity界面。在这个方法中你要处理好用户不再需要的资源,比如停止游戏,停止播放器等,并且需要保存用户现在的数据,比如游戏数据(关卡进度),播放数据(播放进度)等,但是不要进行太耗时的操作。google官网给出的建议是:
官网的例子如下:
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
;
}
}
|
当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方法,当然这是很极端的时候发生的。
Activity生命周期的最后一个方法,一般不会再这个方法里做什么事,应为它有可能不会被调用。大部分的清理工作是在onPause和onStop方法中做的,这个方法是完成清理工作的最后机会,一些可能会引起内存泄露的线程应该在这个方法中停掉,Hander的消息也要清理掉。
我用了两篇文章来给大家聊聊Activity的生命周期和生命周期方法,主要是理解在各个生命周期方法中该做那些事,不该做那些事,这样就能保证UI显示的正确和快速,数据会被保存,该释放的资源会被释放。如果大家有什么问题可以关注下面的公众号给我留言,大家共同讨论。
本文属原创,转载请注明出处,违者必究
关注微信公众平台:程序员互动联盟(coder_online),你可以第一时间获取原创技术文章,和(java/C/C++/Android/Windows/Linux)技术大牛做朋友,在线交流编程经验,获取编程基础知识,解决编程问题。程序员互动联盟,开发人员自己的家。