服务器之家

服务器之家 > 正文

Android中Activity的生命周期探讨

时间:2021-03-10 15:42     来源/作者:Android开发网

Android中Activity的生命周期探讨

1、完整生命周期

上图是android activity的生命周期图,其中resumed、paused、stopped状态是静态的,这三个状态下的activity存在时间较长。

(1)resumed:在此状态时,用户可以与activity进行交互,activity在最前端
(2)paused:在此状态时,activity被另外一个activity遮盖,此activity不可接受用户输入信息。另外一个activity来到最前面,半透明的,但并不会覆盖整个屏幕。
(3)stopped:在此状态时,activity完全被隐藏,不可见。保留当前信息,activity不执行任何代码。
(4)created与started:系统调用oncreate()后迅速调用onstart(),然后迅速执行onresume()。

以上就是android的activity整个生命周期。

2、主activity

用户可以指定程序启动的主界面,此时被声明为“launcher或main”activity的oncreate()方法被调用,成为程序的入口函数。该入口activity可以在androidmanifest.xml中定义主activity。此时,主activity必须使用以下标签声明:

复制代码 代码如下:

<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>

 

3、一个新的activity实例

系统首先调用新activity的oncreate()方法,所以,我们必须实现oncreate()方法。如:声明ui元素、定义成员变量、配置ui等。但是事情不宜太多,避免启动程序太久而看不到界面。

 

复制代码 代码如下:


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);

    // make sure we're running on honeycomb or higher to use actionbar apis
    if (build.version.sdk_int >= build.version_codes.honeycomb) {
        // for the main activity, make sure the app icon in the action bar
        // does not behave as a button
        actionbar actionbar = getactionbar();
        actionbar.sethomebuttonenabled(false);
    }
}

 

oncreate()执行完即调用onstart()和onresume()方法,activity不会在created或者started状态停留。

4、销毁activity

activity的最后一个回调是ondestroy(),系统会执行这个方法做为你的activity要从系统中完全删除的信号。大多数app不需实现此方法,因为局部类的references会随着activity的销毁而销毁。并且activity应该在onpause()和onstop()方法中执行清楚activity资源的操作。如果activity在oncreate()时创建的后台线程,或者是其他有可能导致内存泄露的资源,你应该在ondestroy()时杀死它们。

复制代码 代码如下:


@override
public void ondestroy() {
    super.ondestroy();  // always call the superclass

 

    // stop method tracing that the activity started during oncreate()
    android.os.debug.stopmethodtracing();
}

 

系统通常是在执行了onpause()与onstop()后在调用ondestroy(),除非在oncreate()中调用了finish()。例如,如果你的activity只是做了一个临时的逻辑跳转功能,它使用用来决定跳转到下一个activity,这样,你需要在oncreate()中调用finish()方法。系统就会直接调用ondestroy方法,其他生命周期就不会被执行。

5、暂停与恢复

当前activity被其它可见组件阻塞,当前activity部分可见,当前activity进入pause状态。系统调用activity中的onpause()方法,执行onresume()方法恢复。

当前activity被其它组件完全阻塞,当前activity完全不可见,则当前activity进入stop状态。

当系统调用你的activity中的onpause(),从技术上讲,那意味着你的activity仍然处于部分可见的状态。通常在onpause()回调方法里面做下面的事情。

(1)停止动画或者其他正在运行的操作,减少cpu浪费
(2)提交没有保存的改变,但仅仅是用户离开时保存的内容,如邮件
(3)释放系统资源,如broadcast receivers、sensors、gps或者其他任何影响电量的资源。
(4)如果程序正在使用camera,onpause()会是一个比较好的地方去释放资源的操作。

 

复制代码 代码如下:


@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;
    }
}

 

通常,不应该使用onpause()来保存用户改变的数据到永久存储上,当你确认用户期待那些改变能够自动保存的时候,才可以把那些数据存储到永久存储。然而,应该避免在onpause()时执行cpu-intensive的工作,例如写数据到db,因为他会导致切换activity变得缓慢。这些工作应该放到onstop()中去坐。

如果,activity实际上要被stop,那么应减少在onpause中的工作量,提高流畅性。

恢复activity

用户从pause状态恢复时,调用onresume()方法。此时activity处于最前台,包括第一次创建时,此时,应该在onresume中初始化那些你在onpause方法里释放掉的组件,并执行那些activity每次进入resumed state都需要的初始化动作。

复制代码 代码如下:


@override
public void onresume() {
    super.onresume();  // always call the superclass method first

 

    // get the camera instance as the activity achieves full user focus
    if (mcamera == null) {
        initializecamera(); // local method to handle camera init
    }
}

 

6、停止与重启activity

恰当的停止与重启activity会使用户感知程序的进行。下面一些场景涉及停止与重启:

(1)用户打开最近使用的app的菜单并切换到另外一个app,此时,你的app是被停止的,用户回到你的app,那么你的activity被重启。
(2)用户在app中启动一个新的activity的操作,当前activity会在新activity创建后stop,如果用户点击back按钮,回到上一个activity,重启
(3)用户使用app,接到来电时。

停止状态ui不可见。系统在activity停止时会在内存中保存了activity实例,有时不需事先onstop(),onrestart()甚至onstart()方法,因为大多数的activity相对简单,activity会自己停止与重启。你只需要使用onpause来停止正在运行的动作,并断开系统资源链接。

Android中Activity的生命周期探讨

上图显示:当用户离开你的activity,系统会调用onstop()来停止activity,用户返回时调用onrestart(),然后迅速调用onstart()与onresume(),无论什么原因导致activity停止,系统总会在onstop之前调用onpause

停止activity

当你的activity调用onstop方法,activity不再可见,并且应该释放那些不再需要的所有资源,一旦你的activity停止了,系统会在不需要的这个activity时销毁它的实例。在极端情况下,系统会直接杀死你的app进程,并且不执行activity的ondestroy()回调函数,因此你需要在onstop()来释放资源,否则内存泄露。尽管onpause方法在onstop之前调用,应应该使用onstop来执行cpu-intensive的shut-down操作。如写数据到db。

当activity停止,其对象会保存在内存中,并且在resume时重新调用,不需在恢复到resumed state状态前初始化那些被保存在内存中得组件,系统为我们保存了每一个在布局中的视图的当前状态。即使系统会在activity stop时销毁这个activity,它仍然会保存view对象的状态到一个bundle中,并且在用户返回这个activity时恢复他们。

重新创建activity:当activity在屏幕被旋转时,会被destroy与recreated。此时会加载一些alternative的资源,如layout。默认情况下,系统使用bundle实例来保存每一个视图对象中得信息。为了使android系统能够恢复activity中的view状态,每个view都必须有一个唯一的id

为了确保额外更多的数据到saved instance state,在activity的声明周期里面存在一个添加的回调函数,必须重写onsaveinstancestate(),当用户离开你的activity时,系统会调用它。当系统调用这个函数时,系统会在你的activity被一场destroy时传递bundle对象,这样,你可以增加额外的信息到bundle中,并保存在系统中。如果系统在activity被destroy之后想重新创建这个activity实例时,之前的那个bundle对象会被传递到activity的onrestoreinstancestate()方法和oncreate()方法中。

Android中Activity的生命周期探讨

保存activity状态:当activity开始stop时,系统会调用onsaveinstancestate(),因此你的activity可以用键值对的集合来保存状态信息,这个方法会默认保存activity视图的状态信息,例如在edittext组件中得文本或者是listview的滑动位置。为了给activity保存额外的状态信息,你必须实现onsaveinstancestate()并增加键值对到bundle中。如:

 

复制代码 代码如下:


static final string state_score = "playerscore";
static final string state_level = "playerlevel";
...

 

@override
public void onsaveinstancestate(bundle savedinstancestate) {
    // save the user's current game state
    savedinstancestate.putint(state_score, mcurrentscore);
    savedinstancestate.putint(state_level, mcurrentlevel);

    // always call the superclass so it can save the view hierarchy state
    super.onsaveinstancestate(savedinstancestate);
}

 

恢复activity状态:当你的activity从destroy中重建,你可以从系统传递给你的activity的bundle中恢复保存的状态。oncreate()与onrestoreinstancestate()回调方法都接收到了同样的bundle,里面包含同样的实例状态信息。因为oncreate()方法会在第一次创建新的activity实例与重新创建之前被destroy的实例时都被调用,你必须尝试读取bundle对象之前检查它是否为null,如果为null,系统第一次创建新activity。否则是恢复被destroy的activity。

 

复制代码 代码如下:


protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate); // always call the superclass first

 

    // check whether we're recreating a previously destroyed instance
    if (savedinstancestate != null) {
        // restore value of members from saved state
        mcurrentscore = savedinstancestate.getint(state_score);
        mcurrentlevel = savedinstancestate.getint(state_level);
    } else {
        // probably initialize members with default values for a new instance
    }
    ...
}

 

我们可以选择实现onrestoreinstancestate(),而不是在oncreate方法里恢复数据。onrestoreinstancestate()方法会在onstart()方法之后执行,系统仅仅会在存在需要恢复的状态信息时才会调用onrestoreinstancestate(),因此不需检查bundle是否为null。

 

复制代码 代码如下:


public void onrestoreinstancestate(bundle savedinstancestate) {
    // always call the superclass so it can restore the view hierarchy
    super.onrestoreinstancestate(savedinstancestate);

 

    // restore state members from saved instance
    mcurrentscore = savedinstancestate.getint(state_score);
    mcurrentlevel = savedinstancestate.getint(state_level);
}

 

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部