您的位置:首页 > Web前端

2-1 Managing the Activity Lifecycle

2012-09-02 00:06 302 查看
Activity

Activity是Android程序的4大组件之一。
Activity是Android程序的表示层。程序的每一个显示屏幕就是一个Activity。
学过WEB开发者,可以把Activity理解成网页中的一个JSP文件;或者你可以把它理解成一个Windows的窗口。

下面看一下Activity类的继承关系:





从这里可以看到Activity是Context类的子类。

Activity的生命周期

当用户的焦点进入,离开,或返回时,应用程序中的activity会在它们生命周期中的不同状态进行转换,比如,当activity第一次创建时,它会位于系统屏幕最前面接受用户焦点,在这一过程中,系统会调用activity上的一系列生命周期方法,从而成生用户界面或其它组件

Activity的生命周期不是自身控制的,而是由Android系统控制的。

虽然不是每一次的交互都会经历所有的生命周期方法,但对生命周期方法的了解是很重要的,才能更好的了解跟满足用户对系统行为的要求:

当用户接到电话或切换其它的应用程序时,不要突然消毁;

当用户不处理活动状态时,不要过份的消耗系统资源;

当用户焦点离开,不久又返回到应用程序时,不要丢失用户的流程数据;

当用户在横屏与竖屏之间切换时,不要消毁或丢失用户流程数据。

在android中Activity有四种基本状态:
1、Running

位于屏幕最前端时,此时处于可见状态,和用户可交互的状态(也叫Resumed)。
2、Paused
当Acitivy被另一个透明的或者非全屏的Activity覆盖时的状态叫Paused状态,虽然可见但不可交互。
3、Stopped
当Activity被另外一个Activity覆盖、界面不可见时处于Stop状态。
4、Killed
Activity被系统杀死或者跟本没启动时就是Killed状态。

其它的状态(Created和Started)是短暂的,系统通过调用下一下生命周期方法很快从它们转向下一个状态,可以这么说,当系统调用onCreate()后,会很快的调用onStart(),紧接着很快的调用onResume()

我们下面看一下Activity的生命周期:





指定系统起动自动加载APP,(程序入口)

当用户起动应用程序时,系统调用被声明为launchar(或main)的Activity的onCreate()方法,这一方法通过AndroidManifest.xml实现

例如:

<activityandroid:name=".MainActivity"android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>


创建一个新的实例

大多数程序都包含很多不同功能的Activity,系统通过调用Activity的Oncreate()方法对它们进行创建,我们可以通过onCreate()方法实现基本的程序起动逻辑,针对某些只需要在整个生命周期中只执行一次的逻辑,

一旦onCreate()方法执行完成,onStart()和onResume()紧接着会被调用,当onStart()被调用时用户界面是可见的了,然后调用onResume()方法,从此,Activity保持resumed状态直到某些操作改变了这一状态,如电话打进来,用户切换到另一个Activity或用户关闭屏幕等。

挂起Activity

当系统调用onPause()时,意味着你的Activity挂起,部分可见,最常见的就是用户焦点离开,过一段时间就会进入到Stoped状态,我们经常使用onPause()来实现以下操作:

停止活跃的或其它正在进行的占用CPU的处理;

提交善未保存的更改,当用户离开时,只接受用户持久化的存储;

释放系统资源,如广播接受者,GPS或其它浪费,响影系统电源的资源。

比如,如果你的程序使用相机,the 
onPause()
方法是一个不错的释放它的地方

@Override
publicvoidonPause(){
super.onPause();//Alwayscallthesuperclassmethodfirst

//ReleasetheCamerabecausewedon'tneeditwhenpaused
//andotheractivitiesmightneedtouseit.
if(mCamera!=null){
mCamera.release()
mCamera=null;
}
}


一般情况下,我们不建议在onPause()存储用户的更改到持久化设备,唯一能使用这一方法进行此操作的情况是你确信用户需要把他的更改自动存储

Note:Whenyouractivityispaused,the
Activity
 instanceiskeptresidentinmemoryandisrecalledwhentheactivityresumes.Youdon’tneedtore-initializecomponentsthatwerecreatedduringanyofthecallbackmethodsleadinguptotheResumedstate.

恢复Activity

当Activity从挂起状态被用户恢复时,系统调用onResume()方法。

值得注意的是,当你的Activity被切到屏幕前面,获得焦点时,这个方法都会被调用,把括第一次被创建时,因此,我们必须在onRsume()里初始化那些在onPsuse()里被释放的组件跟那些Activity进入恢复状态都必须初始化的操作,

下面的例子初始化我们在onPause()里释放的相机实例;

@Override
publicvoidonResume(){
super.onResume();//Alwayscallthesuperclassmethodfirst

//GettheCamerainstanceastheactivityachievesfulluserfocus
if(mCamera==null){
initializeCamera();//Localmethodtohandlecamerainit
}
}


停止Activity

什么况下会停止Activity:

当用户切换到另外的应用程序,你应用程序当前的Activity将停止,当用户从程序国标或现在应用程序返回到你的Activity时,Activity将会重新启动;

当你的应用程序开启一个新的Activity时,当新的Activity被创建时当前的Activity将会停止,如果现在用户按返回按钮,原先的Activity将会重新启动;

当用户正在使用你的程序,收到来电时

在停止的状态下,整个Activity都是不可见的,

Note:Becausethesystemretainsyour
Activity 
instanceinsystemmemorywhenitisstopped,it'spossiblethatyoudon'tneedtoimplementthe
onStop()
and
onRestart()
(oreven
onStart()
methodsatall.Formostactivitiesthatarerelativelysimple,theactivitywillstopandrestartjustfineandyoumightonlyneedtouse
onPause()
topauseongoingactionsanddisconnectfromsystemresources.

当系统调用onStop()方法时,Activity将不可见,且系统必须释放几乎所有用户不再使用的资源,虽然onPause()在onStop()之前被调用,但最好使用onStop()进行大型,占用CPU的操作,比如将数据存储到数据库中。

@Override
protectedvoidonStop(){
super.onStop();//Alwayscallthesuperclassmethodfirst

//Savethenote'scurrentdraft,becausetheactivityisstopping
//andwewanttobesurethecurrentnoteprogressisn'tlost.
ContentValuesvalues=newContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE,getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE,getCurrentNoteTitle());

getContentResolver().update(
mUri,//TheURIforthenotetoupdate.
values,//Themapofcolumnnamesandnewvaluestoapplytothem.
null,//NoSELECTcriteriaareused.
null//NoWHEREcolumnsareused.
);
}

当Activity停止时,其实例还是驻在内存中,当Activity恢复时,它会被重新调用,我们不需要重新初始化组件,系统同时会跟踪布局中所有视图的当前状态,所以如果用户输入TEXT到Editextwidget,我们不需要保存或再次重新加载它,在恢复时内容会保留。

Note:Evenifthesystemdestroysyouractivitywhileit'sstopped,itstillretainsthestateofthe
View
objects(suchastextinan
EditText
)ina
Bundle
(ablobofkey-valuepairs)andrestoresthemiftheusernavigatesbacktothesameinstanceoftheactivity(thenextlessontalksmoreaboutusinga
Bundle
tosaveotherstatedataincaseyouractivityisdestroyedandrecreated).

启动或重启你的Activity

当你的Activity从停止状态重新获得焦点时,系统将调用onRstart()方法,系统同时也会调用onStart()方法,onStart()每次都会被调用,不管你是恢复Activity还是第一次创建Activity,但onRestart()只当Activity从停止状态恢复时被调用,你可以用它来做一些只当Activity从停止状态恢复时才需要做的恢复工作。

因为onStop()清理你Activity所有的资源,当Activity重新启动时,我们必须重新初始化这些资源,另外,当我们第一次创建Activity实例时,我们也必须初始化这些资源,因此,我们通常使用onStart()作为onStop()的镜像操作方法,因为当Activity第一次创建或从停止状态恢复时,都会调用onStart()方法。

比如:

becausetheusermighthavebeenawayfromyourappforalongtimebeforecomingbackit,the
onStart()
methodisagoodplacetoverifythatrequiredsystemfeaturesareenabled:

@Override
protectedvoidonStart(){
super.onStart();//Alwayscallthesuperclassmethodfirst

//Theactivityiseitherbeingrestartedorstartedforthefirsttime
//sothisiswhereweshouldmakesurethatGPSisenabled
LocationManagerlocationManager=
(LocationManager)getSystemService(Context.LOCATION_SERVICE);
booleangpsEnabled=locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

if(!gpsEnabled){
//CreateadialogherethatrequeststheusertoenableGPS,anduseanintent
//withtheandroid.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGSaction
//totaketheusertotheSettingsscreentoenableGPSwhentheyclick"OK"
}
}

@Override
protectedvoidonRestart(){
super.onRestart();//Alwayscallthesuperclassmethodfirst

//Activitybeingrestartedfromstoppedstate
}


销毁Activity

生命周期的最后一个方法是onDestroy,当Activity实例完成后被从系统内存中移除时调用,大多数应用程序不用重写实现这一方法,大多数的清理工作建议放在onPause()要onStop()方法中实现,但是,如果你的应用程序包含后台线程或其它占用资源的可以导致内存泄露的任务,我们必须在onDestroy()中杀了这些进程。

Note:ThesystemcallonDestroy()afterithasalreadycalledonPause()andonStop()inallsituationsexceptone:whenyoucallfinish()fromwithintheonCreate()method.Insomecases,suchaswhenyouractivityoperatesasatemporarydecisionmakertolaunchanotheractivity,youmightcallfinish()fromwithin
onCreate()
todestroytheactivity.Inthiscase,thesystemimmediatelycalls
onDestroy()
withoutcallinganyoftheotherlifecyclemethods.

重新创建Activity

以下情况系统会销毁Activity:

1,当用户按下Back按钮或者你的Activity用finish()指定销毁实例

2,当Activity长时间停止且不再被使用,当前的Activity要求更多的系统资源时,系统可能会销毁后台的Activity以释放内存空间。

第一种情况,系统认为此实例可以不用重新创建,用户行为已表明此实例是不再需要的。但是,如果Activity是让系统强制销毁,虽然实例已被销毁,但系统会记下被销毁的Activity的状态,当用户焦点再次回到此Activity时,系统会使用保存下来的数据重新创建Activity,这些保存下来的数据叫”Insancestate”,是存储在Bundle对象中的key-value对。

默认情况下,系统使用Bundle对象保存Activity布局中每一个view的信息(如EditText中输入的内容),所以,当Activity被重新创建时,布局状态自动恢复到之前的状态,但是,我们可能想保存更多的状态信息,

onSaveInstanceState()
onRestoreInstanceState()可以帮到我们,当用户离开Activity时,onSaveInstanceState()会被调用,
[code]Bundle对象会当参数传给它,我们可以添加额外想要的信息。当系统需要重新创建Activity时,同样的
Bundle
对象会传给
onRestoreInstanceState()
方法,同时传给
onCreate()完成Activity的重新创建。






下面举一下例子:

当Activity准备停止时,系统调用
onSaveInstanceState()
方法,所以Activity采用Key-value对的方法保存状态信息,为了保存额外的信息,我们必须重写
onSaveInstanceState()
方法;

staticfinalStringSTATE_SCORE="playerScore";
staticfinalStringSTATE_LEVEL="playerLevel";
...

@Override
publicvoidonSaveInstanceState(BundlesavedInstanceState){
//Savetheuser'scurrentgamestate
savedInstanceState.putInt(STATE_SCORE,mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL,mCurrentLevel);

//Alwayscallthesuperclasssoitcansavetheviewhierarchystate
super.onSaveInstanceState(savedInstanceState);
}


当Activity销毁后重新创建时,我们可以利用Bundle对象实现Activity状态的复原。

如果我们在onCreate()中恢复状态,因为
onCreate()
方法在系统第一次新建Activity实例或Activity得新创建时都会被调用,我们必须判断bundle对象是不是为NULL

Forexample,here'showyoucanrestoresomestatedatain
onCreate()


@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);//Alwayscallthesuperclassfirst

//Checkwhetherwe'rerecreatingapreviouslydestroyedinstance
if(savedInstanceState!=null){
//Restorevalueofmembersfromsavedstate
mCurrentScore=savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel=savedInstanceState.getInt(STATE_LEVEL);
}else{
//Probablyinitializememberswithdefaultvaluesforanewinstance
}
...
}


onRestoreInstanceState()实现状态复原
,系统调用
onStart()
后将调用此方法.系统只会在有状态需要复原时才会调用
onRestoreInstanceState(),所以不需要判断bundle对象是不是为NULL,如下:


publicvoidonRestoreInstanceState(BundlesavedInstanceState){
//Alwayscallthesuperclasssoitcanrestoretheviewhierarchy
super.onRestoreInstanceState(savedInstanceState);

//Restorestatemembersfromsavedinstance
mCurrentScore=savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel=savedInstanceState.getInt(STATE_LEVEL);
}


Activity栈(转):
Android通过Activity栈的方式来管理Activity。

正在运行的Activity处在在栈的最顶端,它是运行状态的;

当有新Activity进入屏幕最上端时,原来的Activity就会被压入第二层,如果他的屏幕没有被完全遮盖,那么他处于Pause状态,如果他被遮盖那么他处于Stop状态。

当然不管你出于任何一层,都可能在系统觉得资源不足时被强行关闭,当然关闭时在栈底的程序最先被关闭。

譬如:当你在程序中调用Activity.finish()方法时,结果和用户按下BACK键一样:他告诉ActivityManager该Activity实例可以被“回收”。随后ActivityManager激活处于栈第二层的Activity并重新入栈,把原Activity压入到栈的第二层,从Running状态转到Paused状态。

实例:观察翻转屏幕导致的Activity状态变化

Activity类中定义了和生命周期相关的一些方法,这些方法会在状态改变时被调用,譬如创建时调用的方法onCreate()。因此我们可以写一个程序,在程序的每个一个方法中写注释,然后看看运行时注释的打印顺序来跟踪Activity的状态变化。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: