Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx

上传人:b****3 文档编号:17233051 上传时间:2022-11-29 格式:DOCX 页数:27 大小:529.35KB
下载 相关 举报
Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx_第1页
第1页 / 共27页
Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx_第2页
第2页 / 共27页
Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx_第3页
第3页 / 共27页
Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx_第4页
第4页 / 共27页
Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx

《Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx》由会员分享,可在线阅读,更多相关《Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx(27页珍藏版)》请在冰豆网上搜索。

Android开发艺术探索笔记第一章Activity的生命周期和启动模式Word下载.docx

onResume:

表示Activity已经可见了,并且出现在前台,并开始活动了,要注意这个和onStart的对比,这两个都表示Activity已经可见了,但是onStart的时候Activity还处于后台,onResume的时候Activity才显示到前台

onPause:

表示Activity正在停止,正常情况下,紧接着onStop就会被调用,在特殊情况下,如果这个时候再快速的回到当前Activity,那么onResume就会被调用,主席的理解是这个情况比较极端,用户操作很难重现这个场景,此时可以做一些数据存储,停止动画等工作,但是注意不要太耗时了,因为这样会影响到新的Activity的显示,onPause必须先执行完,新Activity的onResume才会执行

onStop:

表示Activity即将停止,同样可以做一些轻量级的资源回收,但是不要太耗时了

onDestroy:

表示Activity即将被销毁,这是Activity生命周期的最后一个回调,在这里我们可以做一些最后的回收工作和资源释放

正常情况下,Activity的常用生命周期用官网的一张图就足够表示了

这里附加几个说明

1.针对一个特定的Activity,第一次启动,回调如下:

onCreate——>

onStart——>

onResume

2.当用户打开新的Activity或者切换到桌面的时候,回调如下:

onPause——>

onStop——>

这里有一种特殊的情况就是,如果新的Activity采取了透明的主题的话,那么当前Activity不会回调onStop

3.当用户再次回到原来的Activity,回调如下:

onRestart——>

4.d当用户按back键的时候回调如下:

onPause———>

onDestroy

5.当Activity被系统回收的时候再次打开,生命周期回调方法和1是一样的,但是你要注意一下就是只是生命周期一样,不代表所有的进程都是一样的,这个问题等下回详细分析

6.从整个生命周期来说,onCreate和onDestroy是配套的,分别标示着Activity的创建和销毁,并且只可能有一次调用,从Activity是否可见来说,onStart和onStop是配套的,随着用户的操作和设备屏幕的点亮和熄灭,这两个方法可能被调用多次,从Activity是否在前台来说,onResume和onPause是配套的,随着用户操作或者设备的点亮和熄灭,这两个方法可能被多次调用

这里提出两个问题

1.onStart和onResume,onPause和onStop从描述上都差不多,对我们来说有什么实质性的不同呢?

2.假设当前Activity为A,如果用户打开了一个新的Activity为B,那么B的onResume和A的onPause谁先执行尼?

我们先来回答第一个问题,从实际使用过程来说,onStart和onResume,onPause和onStop看起来的确差不多,甚至我们可以只保留其中的一对,比如只保留onStart和onStop,既然如此,那为什么Android系统还会提供看起来重复的接口呢?

根据上面的分析,我们知道,这两个配对的回调分别代表不同的意义,onStart和onStop是从Activity是否可见这个角度来回调的,除了这种区别,在实际的使用中,没有其他明显的区别

第二个问题,我们就要从源码的角度来分析以及得到解释了,关于Activity的工作原理会在本书后续章节进行讲解,这里我们大致的了解即可,从Activity的启动过程来看,我们来看一下系统的源码,Activity启动过程的源码相当复杂,设计到了Instrumentation,Activit和ActivityManagerService(AMS),这里不详细分析这一过程,简单理解,启动Activity的请求会由___Instrumentation来处理,然后他通过Binder向AMS发请求,AMS内部维护着一个ActivityStack,并负责栈内的Activity的状态同步,AMS通过ActivityThread去同步Activity的状态从而完成生命周期方法的调用,在ActivityStack中的resumeTopActivityLnnerLocked方法中,有这么这段代码

//weneedtostartpausingthecurrentactivitysothetoponecanberesumed

booleandontWaitForPause=(next.info.flags&

ActivityInfo.FLAG_RESUME_WHILE_PAUSING)!

=0;

booleanpausing=mStackSupervisor.pauseBackStacks(userLeaving,KeyStore.TrustedCertificateEntry,dontWaitForPause);

if(mResumedActivity!

=null){

pausing!

=startPaUSINGlOCAKED(userLeaving,false,true,dontWaitForPause);

if(DEBUG_STATES){

Slog.d(TAG,"

resumeTopActivityLocked:

pausing"

+mResumedActivity);

}

从上述的代码中我们可以看出,在新Activity启动之前,栈顶的Activity需要先onPause后,新的Activity才能启动,最终,在ActvityStackSupervisor中的realStartActivityLocked方法中,会调用如下代码

app.thread.scheduleLaunchActivity(newIntent(r.intent),r.appToken,System.identityHashCode(r),r.info,newConfiguration(mService.mConfiguration)

pat,r.task.voiceInteractor,app.repProcState,r.icicle,r.persistentState,results,newIntents,!

andResume,mService.isNextTransitionForward()

profilerInfo);

我们都知道,在这个app.thread的类型是IApplicationThread的具体实现实在ActivityTread中,所以,这段代码实际上遇到了ActivityThread当中,,即ApplicationThread的scheduleLaunchActivity方法,而scheduleLaunchActivity方法最终会完成生命周期的调用过程,因此可以得出结论,是旧Activity县onPause,然后新的Activityy再启动

至于ApplicationThread的scheduleLaunchActivity方法为什么会完成新Activity的生命周期,请看接下来的代码,scheduleLaunchActivty为什么会完成新的Activty

privatevoidhandlerLaunchActivity(ActivityClientRecordr,IntentcustomIntent){

//ifwearegettingreadytogcaftergoingtothebackground,wellwearebackactivesoskipit

unscheduleGcIdler();

mSomeActivitiesChanged=true;

if(r.profilerInfo!

mProfiler.setProfiler(r.profilerInfo);

mProfiler.startProfiling;

//Makesurewearerunningwiththemostrecentconfig

handlerConfigurationChanged(null,null);

if(localLOGV)Slog.v

TAG,"

Handlinglaunchof"

+r);

//在这里新Activity被创建出来,其onCreate和onStart被调用

Activitya=PerformLaunchActivity(r,customIntent);

if(a!

r.createdConfig=newConfiguration(mConfiguration);

BundleoldState=r.start;

handlerResumeActivity(r.token,false,r.isForward,

!

r.activity.mFinished&

&

r.startsNotResumed);

//省略...

c从上面的分析可以看出,当新的Activity启动的时候,旧的Activity的onPause方法会先执行,然后才启动新的Activity,到底是不是这样尼?

我们可以写一个小栗子来验证一下,如下是两个Activity的代码,在MainActivity中点击按钮可以跳转到SecondActivity,同时为了分析生命周期,我们把log日志也打出来

MainActivity

packagecom.liuguilin.activitysample;

importandroid.content.Intent;

importandroid.os.Bundle;

importandroid.support.v7.app.AppCompatActivity;

importandroid.util.Log;

importandroid.view.View;

publicclassMainActivityextendsAppCompatActivity{

publicstaticfinalStringTAG="

MainActivity"

;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

findViewById(R.id.btnTo).setOnClickListener(newView.OnClickListener(){

publicvoidonClick(Viewview){

startActivity(newIntent(MainActivity.this,SecondActivity.class));

});

protectedvoidonPause(){

super.onPause();

Log.i(TAG,"

onPause"

);

protectedvoidonStop(){

super.onStop();

onStop"

}

SecondActivity

/**

*Createdbylglon16/8/24.

*/

publicclassSecondActivityextendsAppCompatActivity{

privatestaticfinalStringTAG="

SecondActivity"

setContentView(R.layout.activity_second);

onCreate"

protectedvoidonStart(){

super.onStart();

onStart"

protectedvoidonResume(){

super.onResume();

onResume"

这样我们可以观察到他的生命周期

通过这个生命周期我们可以观察到,旧的Activity的onPause先调用,然后新的Activity才启动,这也证实了我们上面的分析原理,也许有人问,你只是分析了Andorid5.0的源码,你怎么所有的版本源码逻辑都相同,的确,我们不能把所有的版本都概括,但是作为Android的一个运行过程的基本逻辑,随着版本的更新并不会很大的改变,因为Android也需要兼容性,,不能说在同一个版本上运行有两种不同的逻辑,那根本不可能,关于这一点,我们要把握一个度,就是对于Android的基本运行机制,的不同,Android不能在onPause中做重量级的操作,因为必须在onPause执行完成以后新的Activity才能Resume,从这一点我们也间接性的证明了我们的结论,通过分析这个问题,我们知道onPause和onStop都不能做耗时的操作,尤其是onPause,这也意味着,我们应当尽量的在onStop中做操作,从而使新的Activity尽快显示出来并且换到前后台

三.异常情况下的生命周期分析

上一节我们分析的是正常事情下的生命周期,但是我们写程序也不要理想化,居多的问题就是出在异常情况下,我们知道,Activity除了受用户操作导致的正常生命周期的调度,同时还会存在一些异常的情况,比如当资源相关的系统配置发生改变以及系统内存不足的时候,Activity就有可能被杀死,下面我们具体来分析下这几种情况

1.情况1:

资源相关的系统配置发生改变导致Activity被杀死并重新创建

理解这个问题,首先要对系统的资源加载有一定的了解,这里就不详细分析系统资源加载的机制了,但是我们简单说明一下,拿最简单的图片来说,当我们把一张图片挡在drawable中的时候,就可以通过Resources去获取这张图片了,同时为了兼容不同的设备,我们可能还需要在其他一些目录下放置不同的图片,比如drawable-xhdpi之类的,当应用程序启动时,系统会根据当前设备的情况去加载合适的Resources资源,比如说横屏手机和竖屏手机会拿着两张不同的图片(设定了landscape或者portrait状态下的图片),比如之前Activity处于竖屏,我们突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity会被销毁并且重新创建,当然我们也可以阻止系统重新创建我们的Activity

默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变之后,Activity就会销毁并且重新创建,可以看图

当系统配置发生改变的时候,Activity会被销毁,其onPause,onStop,onDestroy均会被调用,同时由于Activity是异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态,这个方法调用的时机是在onStop之前,他和onPause没有既定的时序关系,他即可能在onPause之前调用,也有可能在之后调用,需要强调的是,这个方法只出现在Activity被异常终止的情况下,正常情况下是不会走这个方法的吗,当我们onSaveInstanceState保存到Bundler对象作为参数传递给onRestoreInstanceState和onCreate方法,因此我们可以通过onRestoreInstanceState和onCreate方法来判断Activity是否被重建。

如果被重建了,我们就取出之前的数据恢复,从时序上来说,onRestoreInstanceState的调用时机应该在onStart之后

同时我们要知道,在onSaveInstanceState和onRestoreInstanceState方法中,系统自动为我们做了一些恢复工作,当Activity在异常情况下需要重新创建时,系统会默认我们保存当前的Activity视图架构,并且为我们恢复这些数据,比如文本框中用户输入的数据,ListView滚动的位置,这些View相关的状态系统都会默认恢复,具体针对某一个特定的View系统能为们恢复那些数据?

我们可以查看View的源码,和Activity一样,每一个View都有onSaveInstanceState和onRestoreInstanceState这两个方法,看一下他们的实现,就能知道系统能够为每一个View恢复数据

关于保存和恢复View的层次结构,系统的工作流程是这样的:

首先Activity被意外终止时,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window再委托上面的顶级容器去保存数据,顶级容器是一个ViewGroup,一般来说他可能是一个DecorView,最后顶层容器再去一一通知他的子元素来保存数据,这样整个数据保存过程就完成了,可以发现,这是一种典型的委托思想,上层委托下层,父容器委托子容器,去处理一件事件,这种思想在Android中有很多的应用,这里就不再重复介绍了,接下来举个例子,那TextView来说,我们分析一下他到底保存了那些数据

publicParcelableonSaveInstanceState(){

ParcelablesuperState=super.onSaveInstanceState();

//Savestateifweareforcedto

booleansave=mFreezesText;

intstart=0;

intend=0;

if(mText!

=null){

start=getSelectionStart();

end=getSelectionEnd();

if(start>

=0||end>

=0){

//Orsavestateifthereisaselection

save=true;

if(save){

SavedStatess=newSavedState(superState);

//XXXShouldalsosavethecurrentscrollposition!

ss.selStart=start;

ss.selEnd=end;

if(mTextinstanceofSpanned){

Spannablesp=newSpannableStringBuilder(mText);

if(mEditor!

removeMisspelledSpans(sp);

sp.removeSpan(mEditor.mSuggestionRangeSpan);

ss.text=sp;

}else{

ss.text=mText.toString();

if(isFocused()&

start>

=0&

end>

ss.frozenWithFocus=true;

ss.error=getError();

returnss;

returnsuperState;

从上述源码中我们可以看到,TextView为了保存自己的文本选中和文本结构内容,并且通

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 电子电路

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1