android:activity生命周期及几个主要函数应当做的事情

来源:互联网 发布:c语言中求绝对值的代码 编辑:程序博客网 时间:2024/06/16 04:39

本文系作者原创,转载请附原文地址,谢谢。

原文地址:http://write.blog.csdn.net/postedit/47342183


前言:

android的activity生命周期问题是个老生常谈的问题了,各大社区都有很多帖子说这个问题。
如果我说,这篇文章是我百分百原创的,那我自己都要打自己的脸,因为API中已经说了很多内容了,但是API是绝对不会将“个人理解”性的东西放进去的。这篇文章是在谈我看了API,以及同行的文章后自己的理解,并试图让这种理解更有利于程序的规范性。
正如上文所言,是谈理解的,所以不去做翻译工作。
许多前辈在以前对这生命周期问题的正确理解应当得到肯定和尊重。但这里无法像论文中那样。

正文:



Android生命周期图

本来还想语言描述一下,但是发现任何语言在这个经典的图面前都是没有必要的。

首先先看一下API文档说了些什么,(我在word中做了一些缩进效果,到这里反而变乱码)

 

 

Method

Description

Killable?

Next

l  onCreate()

Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.

Always followed by onStart().

No

onStart()

n  onRestart()

Called after your activity has been stopped, prior to it being started again.

Always followed by onStart()

No

onStart()

n  onStart()

Called when the activity is becoming visible to the user.

Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.

No

onResume() or

onStop()

u  onResume()

Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it.

Always followed by onPause().

No

onPause()

u  onPause()

Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.

Followed by either onResume() if the activity returns back to the front, or onStop() if it becomes invisible to the user.

Yes

onResume() or

onStop()

n  onStop()

Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.

Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.

Yes

onRestart() or

onDestroy()

l  onDestroy()

The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.

Yes

Nothing

 

 

 

Activity的6个关键方法的注释:

void android.app.Activity.onCreate(BundlesavedInstanceState)
Called when the activity is starting. Thisis where most initialization should go: calling setContentView(int) toinflate the activity's UI, using findViewById to programmatically interact withwidgets in the UI, calling managedQuery(android.net.Uri, String[], String,String[], String) to retrieve cursors for data being displayed, etc. 
You can call finish from within this function, in which case onDestroy() willbe immediately called without any of the rest of the activity lifecycle(onStart, onResume, onPause, etc) executing.

void android.app.Activity.onStart()

Called after onCreate — or after onRestartwhen the activity had been stopped, but is now again being displayed to theuser. It will be followed by onResume.

 

void android.app.Activity.onResume()

Called after onRestoreInstanceState,onRestart, or onPause,for your activityto start interacting with the user. This is a good place to begin animations,open exclusive-access devices (such as the camera), etc. 

Keep in mind that onResume is not the bestindicator that your activity is visible to the user; a system window such asthe keyguard may be in front. Use onWindowFocusChanged to know for certain thatyour activity is visible to the user (for example, to resume a game). 

 

void android.app.Activity.onPause()

Called as part of the activity lifecycle when an activity is going into thebackground, but has not (yet) been killed. The counterpart toonResume. 

When activity B is launched in front ofactivity A, this callback will be invoked on A. B will not be created until A'sonPause returns, so be sure to not do anything lengthy here. 

This callback is mostly used for savingany persistent state the activity is editing, to present a "edit inplace" model to the user and making sure nothing is lost if there are notenough resources to start the new activity without first killing this one. Thisis also a good place to do things like stop animations and other things thatconsume a noticeable amount of CPU in order to make the switch to the nextactivity as fast as possible, or to close resources that are exclusive accesssuch as the camera. 

In situations where the system needs morememory it may kill paused processes to reclaim resources. Because of this,you should be sure that all of your stateis saved by the time you return from this function. In generalonSaveInstanceState is used to save per-instance state in the activity and thismethod is used to store global persistent data (in content providers, files,etc.) 

After receiving this call you will usuallyreceive a following call to onStop (after the next activity has been resumedand displayed), however in some cases there will be a direct call back toonResume without going through the stopped state. 

 

void android.app.Activity.onStop()

Called when you are no longer visible tothe user. You will next receive either onRestart, onDestroy, or nothing,depending on later user activity. 

Note thatthis method may never be called,in low memory situations where the systemdoes not have enough memory to keep your activity's process running after itsonPause method is called. 

 

 

protected void onDestroy ()

Perform any final cleanup before anactivity is destroyed. This can happen either because the activity is finishing(someone called finish() on it, or because the system is temporarily destroyingthis instance of the activity to save space. You can distinguish between thesetwo scenarios with the isFinishing() method.

 

Note: donot count on this method being called as a place for saving data! Forexample, if an activity is editing data in a content provider, those editsshould be committed in either onPause() or onSaveInstanceState(Bundle), nothere. This method is usually implemented to free resources like threads thatare associated with an activity, so that a destroyed activity does not leavesuch things around while the rest of its application is still running. Thereare situations where the system will simply kill the activity's hosting processwithout calling this method (or any others) in it, so it should not be used todo things that are intended to remain around after the process goes away.

 

Derived classes must call through to thesuper class's implementation of this method. If they do not, an exception willbe thrown.

 

 

 

可能有些朋友不喜欢英文,那我们结合着一些常见问题,顺带翻译一点内容。虽然这些问题都是老生常谈了,但我觉得有些答案并不算出色。

onCreate()中实现所有的初始化?

是有问题的!

Activity的onCreate()方法被调用时,Activity处于不可见状态,如果做动画等,视图还不存在呢,所以存在问题;

Activity A 切换到 Activity B,再切换到 ActivityA(Single Instance模式,依旧是原来的实例),实例已经存在,onCreate不再被调用,那Activity A从后台切换至前台时,一些有必要的初始化就没法实现,也是存在问题的;

 

是否可以将所有的初始化都在onStart()中实现?

onCreate中:

This is where mostinitialization should go: calling setContentView(int) to inflate the activity'sUI, using findViewById to programmatically interact with widgets in the UI,calling managedQuery(android.net.Uri, String[], String, String[], String) toretrieve cursors for data being displayed, etc.

我想这些内容你不应当忽视。

虽然在onStart()中实现findviewbyid也可行,但我认为这没有必要,因为每次调用onStart()都会重新实例化view、控件。

一些特殊的初始化、变量的注册也不应当放在这里

而且onStart, onResume,onCreate都不是真正visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。这在onResume()中提及

 

是否可以将所有的反注册都在onStop()中实现?

onResume() 的注释中,建议在 onResume()中打开独占设备(比如相机),与 onResume() 对应的是 onPause(),所以所有的去初始化操作放在onStop()中执行,并不合适,应当做该做的事情。

而且onStop() 的注释中明确地写了:在内存不足而导致系统无法保留此进程的情况下,onStop() 不会被执行。

这里我们要谈一下activity跳转时两个activity生命周期的变化,这样才能更好地理解这些重载函数应该执行些什么。

Activity间跳转时(从Activity A跳到Activity B):

1.     调用Activity AonPause()

2.     Activity B的初始化流程(onCreate()--> onStart() --> onResume()),

3.     调用Activity AonStop()

onResume() 的注释中,建议是在 onResume() 中打开独占设备(比如相机),与 onResume() 对应的是 onPause() ,关闭相机的操作也应该在此方法中被调用;

考虑一下如下场景:

Activity A打开了相机,此刻跳转到Activity B,Activity B也要打开相机。

若Activity A的onPause() 在 ActivityB启动后(准确的说是调用Activity B的onResume()之后)再被调用,那Activity B无法打开相机,因为相机作为独占资源被Activity A占用。

onPause() 的注释中指出:在这个方法中执行停止动画等比较耗CPU的操作。如果不先执行这些操作,就先启动新应用,是不合逻辑的;

从用户体验的角度来分析,最后调用onStop()比较合理,当用户触发某事件切换到新的Activity,用户肯定是想尽快进入新的视图进行操作,而调用onStop()是会耗时的(即使很短)。

底层执行Activity A的onPause()时,有一定的时间限制的,当ActivityManagerService通知应用进程暂停指定的Activity时,如果对应的onPause()在500ms内还没有执行完,ActivityManagerService就会强制关闭这个Activity。如下就是对应的onPause()执行超时常量定义:

// How long we wait until giving up on the last activity to pause.

//This is short because it directly impacts the responsiveness of startingthe

// next activity. 

static final int PAUSE_TIMEOUT = 500;  // 定义在ActivityStack.java中

 

 

是时候总结了:

onCreate函数:注册你要用到的变量,比如说service,receiver,这些变量是无论你的Activity是在前台还是在后台都能够被响应到的(这里应当引起注意并关心到onStart),调用setContentView()函数初始化布局信息。

onStart函数:注册一些变量。这些变量必须在Android Activity类在前台的时候才能够被响应(或者这样说更明确,变量的注册更应当放在onCreate中,但是有些变量的注册必须在activity处于前台时才可行,这些则放在onStart中)。

onResume函数:调用一些刷新UI的函数,每当Activity调用到这里时就要刷新一下UI各控件的状态。

onPause函数:一般是做一些变量的设置,或者保存,因为这个时候Activity马上就要切到后台处理,可能有些变量就要被释放掉或者状态要做些相应的调整。

onStop函数:反注册在onStart函数中注册的变量。

onDestory函数:反注册在onCreate函数中注册的变量。


本文系作者原创,转载请附原文地址,谢谢。

原文地址:http://write.blog.csdn.net/postedit/47342183



0 0
原创粉丝点击