您的位置:首页 > 其它

[原创]深入了解Activity生命周期 附源码

2012-06-28 22:42 381 查看
深入了解Activity生命周期

正确理解Activity生命周期对我们开发灵活的Android应用程序有很大的帮助.大家是否有遇到过这样的情况:当在设备屏幕旋转时,用户一些输入的信息将会丢失.如果正确理解了Activity的生命周期,对于这个问题应该很好解决.其实当屏幕在旋转时,Activity已经销毁后又重新创建了.所以在呈现Activity时那些信息就丢失了.

一.管理Activity的生命周期

Activity的三个主要状态

在Android系统中,Activity实际上存在于三种状态:Resumed,Paused,Stopped.

Resumed状态

即Running状态,显示在屏幕上同时有用户输入操作焦点.

Paused状态

失去用户输入操作焦点,但对于用户还是可见的.覆盖Activity可能是透明或者部分覆盖.

Stopped状态

完全被其他Activity覆盖.即进入后台.

Activity状态图



当Activity处理Stopped,Paused状态时,Activity都是出于”存活状态”.也就是Activity对象存活在系统内存中,它继续维护着Activity的所有状态和成员信息.唯一的区别是:

Stopped状态下Activity对象已经与”Window Manager”失去关联.此时对用户来说已经是不可见了.如果某处需要内存时系统会轻易的杀死该Activity.

Paused状态下Activity对象继续与”Window Manager”保持关联.但是系统如果出现内存不足时,系统会杀死该Activity.

Activity的完整生命周期

大家可以通过下图了解到一个Activity从创建到销毁的整个生命流程.通过实现相应的回调方法来保存和恢复一些类似状态,字符串等信息.



矩形代表你可以在代码中重载的方法,例如:onCreate()就是对应我们MainActivity代码中的onCreate方法.

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

wordList = new ArrayList<String>();

adapter = new ArrayAdapter<String>(this,

android.R.layout.simple_list_item_1, android.R.id.text1,

wordList);

setListAdapter(adapter);

doBindService();

}

二.保存Activity的状态

在上述管理Activity的生命周期小节中我们了解到,Activity在Paused,Stopped状态时Activity对象的相关状态和信息是继续保存在系统内存中.所以当重新回到Resumed状态时,可以获取到切换前Activity对象的相关状态和信息.

然而,为了空出更多内存系统将销毁Activity对象.这样系统将无法恢复该Activity对象,取而代之,系统必须重建Activity对象.Android提供”onSaveInstancestate()”回调方法来让开发者手工保存一些状态信息,同时方法会传递一个Bundle对象.所以我们可以将需要保存的信息保存到Bundle对象,然后当系统重现Activity时从onCreate()方法取得Bundle对象来获取当初保存的状态信息.

那么Android是在什么时候来调用”onSaveInstanceState()”方法呢?我们先来看下图.



上图展示了两种途径来返回用户界面,左边的图展示了Activity进入Stopped状态,然后重返到Running状态.这种情况下无需保存状态信息,因为此时Activity对象还保存在内存中并没有被销毁.

右边的图展示了Activity进入Stoppecd状态后,由于其他应用程序需要内存,系统将此Activity销毁,这种情况下就需要保存状态信息.直到重现Activity时再恢复之前保存的信息.

有一点需要注意,”onSaveInstanceState()”方法不是任何时候都会被调用的,当用户在按回退键(Back)时,系统不会调用此方法.Back键的调用顺序是

”onPause()”-> ”onStop()”->”onDestroy()”.这种情况就需要做一些特殊处理,例如将信息保存在静态变量中.大家可以在我的代码基础上作一下修改即可实现.

使用”onSaveInstanceState()”方法只能通过Bundle对象来保存一些简单的信息,如果需要保存更多的,更复杂的数据结构,这种方法就显得不太合适了. 可以使用的另外一种方法是使用”onRetainNonConfigurationInstance()”回调方法.当一个Activity因为配置更改(例如屏幕方向的改变)而Activity销毁的时候,Android系统将调用这个方法.该回调方法的使用我们将在代码实例中演示如何使用?

三.代码实例

最后我们以一个具体示例来总结我们上述所讲的知识.示例是一个简单的登录窗口,在用户输入相关用户信息后,退回到主页或者运行其他程序后,重返到该示例界面时恢复用户之前的输入信息.

界面设计

我们在恢复用户名信息时采用”onSaveInstanceState()”方法,在恢复密码信息时采用” onRetainNonConfigurationInstance()”方法.



主要代码:

public class MainActivity extends Activity {

private EditText etName, etPwd;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

etName = (EditText)this.findViewById(R.id.etUserName);

if (savedInstanceState != null)

etName.setText(savedInstanceState.getString("UserName"));

etPwd = (EditText)this.findViewById(R.id.etPwd);

if (null != getLastNonConfigurationInstance())

etPwd.setText(getLastNonConfigurationInstance().toString());

}

@Override

protected void onPause() {

// TODO Auto-generated method stub

super.onPause();

}

@Override

public Object onRetainNonConfigurationInstance() {

etName = (EditText)this.findViewById(R.id.etUserName);

return etName.getText().toString();

}

@Override

protected void onSaveInstanceState(Bundle outState) {

etName = (EditText)this.findViewById(R.id.etUserName);

String strUName;

if (null != etName) {

strUName = etName.getText().toString();

outState.putString("UserName", strUName);

}

super.onSaveInstanceState(outState);

}

}

希望本文能对广大Android的童鞋们有所帮助,相信理解了Activity的生命周期,对大家今后的开发工作有很大的帮助.如有不足之处,请指出并见谅.关于如何保存Activity状态信息,我会将在后期单独讲解此内容.

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