android.app.Activity

基本类,必须熟知。用户要使用它,就必须从Activity派生出自己的Activity子类。
可以认为它是和用户进行交互的最小的独立的任务单位,所以称之为“活动”。一个活动在和用户进行交互、完成工作的过程中,可以有多个Java线程辅助其工作。
几乎所有的Activity都要和用户进行交互,所以它要创建一个属于自己的UI界面,而且经常是全屏的。当然也可做成浮动窗口的形式,或者嵌入别的Activity中,结成一个组合。

必须要实现的两个方法:
- onCreate(Bundle)
  把Activity的初始化代码放在此处。经常使用setContentView(int)和findViewById(int)来设置UI元素。
- onPause()
  当用户暂时不需要和该Activity交互而离开的时候,系统会回调此方法。此处要保存用户数据!(经常使用ContentProvider)

若想使用Context.startActivity()启动某个Activity,则该Activity必须在AndroidManifest.xml文件中配置自己的<activity>属性。

Activity是一个Android应用程序最重要的组成部分。它影响了应用程序的生存周期、组成方式、启动模式。关于这方面,请看《应用程序基础》和《任务与活动栈》。

Android系统中的所有“活动”是以“活动栈”(activity stack)的形式组织管理的。一个Activity被创建,则被放到栈顶,变成“活动”状态。其它的活动则被压到它的下面。等到什么时候,该活动退出了,则下面的活动又顶上来。

Activity有四种状态:
1> 如果显示在屏幕上,且接收用户输入,则是处于栈顶,是“活动”(active, running)的。
2> 如果显示在屏幕上,但不能接收用户的输入,失去了焦点,则说明有其它的透明的、或非全屏的Activity存在于其上。此时其为“暂停”状态(paused)。处于暂停的Activity,其内部所有信息都仍然存在,而且和“窗口管理器”仍然连接着。但有可能在内存极为紧缺时,被系统强行杀掉。
3> 如果一个Activity完全被其它的Activity挡住了,已经不可见时,是处于“停止”状态(stoped)。它仍然保有内部状态,但其窗口已经隐藏,且常常在内存吃紧时被系统强行杀掉。
4> 当一个Activity暂停或停止时,会被系统喝令终止(finish),或者强行杀掉。当用户重新启动它,它又重获焦点的时候,相当于重新启动,需要自己恢复状态。

这涉及到七个回调函数:
1> onCreate() 从零开始启动
2> onCreate() -> onStart() -> onResume() 处于可见状态,可以和用户交互了
3> 别的应用跑出来,覆盖到它上面,-> onPause()
4> 它完全看不见了,-> onStop()
5> 处于“暂停”状态时,用户重新选择回它,-> onResume() 重又获得焦点
6> 处于“停止”状态时,用户重新选择回它,-> onRestart() -> onStart() -> onResume()...
7> 处于“停止”状态时,长时间不理它,内存少,-> onDestroy()
8> 处于“暂停”或“停止”状态时,内存吃紧,被系统杀掉。此时无回调!

又有三个关键点:
1> 完整的生命周期
   以onCreate()为始,以onDestroy()为终。所以一个Activity要在onCreate()里做初始化工作,在onDestroy()里释放资源。
2> 可见的生命周期
   以onStart()为始,以onStop()为终。此期间,用户可见该Activity在屏幕上(有可能被挡在后台,没和用户交互)。在这两个方法中维护那些要显示到UI上的资源。
   例如,在onStart()里注册(register)一个BroadcastReceiver来监视影响UI的事情;在onStop()里销掉注册(unregister),因为用户已看不到UI了。
   onStart()和onStop()可在整个活动的生命周期内被回调多次。
3> 前台的生命周期
   以onResume()为始,以onPause()为终。处于和用户交互的状态。当然,在活动的生命周期内会被回调多次。

- onCreate(Bundle)
第一次创建时调用。一般地静态初始化工作在此完成。有时带参数,保存着上一次被销毁时所冻结的状态。
onStart()紧跟此方法被回调。

- onRetart()
从停止状态返回到活动状态时被回调。
onStart()紧跟此方法被回调。

- onStart()
处于用户可见的状态时被回调。
若获得用户焦点,则后跟一个onResume();若变为不可见,后跟一个onStop()。

- onResume()
获得用户焦点时回调。后跟onPause()。

- onPause()
当系统退回到以前的Activity时回调。
一般在此外保存用户数据,停止动画及其它耗CPU的工作。因为只有此方法退出时才会真正进入下一个Activity。

- onStop()
用户不可见时被回调。一个新活动被创建,或以前的某活动重获焦点挡在它前面。

- onDestroy()
可在活动被销毁前释放一次资源。有两种情况会调用此方法:1> 有人调用了finish()方法 2> 系统内存吃紧。
可用isFinishing()方法区分二者。
不能靠此方法保存数据!应在onPause()或onSaveInstanceState(Bundle)里执行数据保存操作。onDestroy()只适合释放线程一类的资源,以保证在活动被杀掉后不会遗留东西给正在运行的应用程序。
有时系统会强行杀掉活动而不回调此方法。

- onLowMemory()
系统在内存吃紧时回调此方法,但何时调用没有准确定义。一般而言,系统会先关掉所有的后台进程,最后杀掉作为进程总控和前台UI的主进程。此函数会在主进程被杀前回调。
应用程序若想积极响应内存低的警报,可实现此方法,主动释放资源。系统会在此方法后,自动调用gc回收。

- onRestoreInstanceState (Bundle)
当活动从以前保存的状态重新初始化时,此方法在onStart()以后回调。
大多数应用会在onCreate(Bundle)中恢复状态,但有时某些工作在此处做比较方便。比如直接调用缺省实现,恢复在onSaveInstanceState(Bundle)中被冻结的View的状态。

- onSaveInstanceState (Bundle)
在活动被杀掉前,保存实例里的状态。保存的东西用在onCreate()或onRestoreInstanceState()中。
比如,B活动被创建,A活动被压入栈。那么A有可能会被杀掉。在被杀前可把UI相关的状态存储起来,在以后用户回到A的时候重新恢复出来。
不要和onPause()和onStop()混淆。onPause()被回调的机率大多了;onStop()则是在销毁前被回调。
例如,用户从B回到A,此时不会调用B的onSaveInstanceState(),只调用onPause()和onStop()。因为B不会被恢复。
再例如,B被创建,A被压栈。若在B的生命周期内A没有被杀掉,则不会调用A的onSaveInstanceState(),只调用onPause()。

调用在onStop()之前。和onPause()的前后则无关系,可前可后。

若设备发生“配置改变”事件(比如更换了语言、输入设备,改变了朝向等等),所有的UI要都重新从配置文件中读取资源、布局、文本等数据,然后重新建立UI,呈现给用户。
这将导致Activity发生一系列的状态变化:onPause() -> onStop() -> onDestroy() -> onCreate() -> onResume()... 即重建了整个Activity。
若想忽略某个事件,需在AndroidManifest.xml里配置android:configChanges属性。(同时,实现onConfigurationChanged(Configuration)方法)。

使用startActivity(Intent)启动的新活动会被放到活动栈的顶。Intent参数描述了要启动何种Activity。

有时想在某个Activity结束时获取一个返回值,则要调用startActivityForResult(Intent,int)。则在宿主Activity的onActivityResult(int,int,Intent)里会获取返回值。
寄主Activity要在结束前调用setResult(int)。还可以附加一个Intent作为附加数据。

若寄主Activity未正常结束(比如崩溃了),宿主只会得到一个RESULT_CANCELED返回值。

public class MyActivity extends Activity {
	...
	static final int PICK_CONTACT_REQUEST = 0;

	protected boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
			 startActivityForResult(
				 new Intent(Intent.ACTION_PICK,	// 用户想选择一个联系人
				 new Uri("content://contacts")),// 联系人列表
				 PICK_CONTACT_REQUEST);			// 自定义的Activity ID
			return true;
		}
		return false;
	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == PICK_CONTACT_REQUEST) {
			if (resultCode == RESULT_OK) {		// 把返回的联系人显示给用户
				startActivity(new Intent(Intent.ACTION_VIEW, data));
			}
		}
	}
}

Activity有两种保存数据的方式。
 - 共享文档式的数据(存储到SQLite数据库中);
 - 内部私有的数据,比如“用户偏好”(user preferences)。

第一种存储方案建议使用“即编即存”的模式。有两个要点:
- 建立新文档时,立刻在后台数据库建立一个条目。比如想编辑一条新邮件,马上在数据库建新条目。这样,用户跑到其它Activity时,邮件会自动保存到草稿箱。
- 活动的onPause()回调时,马上保存。保证了数据可被其它运行的activity看到。
这意味着用户按BACK时,不是CANCEL,而是SAVE。

第二种方案,使用getPreferences(int)方法,保存“键值对儿”到该Activity相对应的存储区域。
注意,不同Package之间不能访问这些内部数据。同一Package的不同Activity是可以互访的。

public class CalendarActivity extends Activity {
	...
	static final int DAY_VIEW_MODE = 0;
	static final int WEEK_VIEW_MODE = 1;

	private SharedPreferences mPrefs;
	private int mCurViewMode;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
		mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE);
	}

	protected void onPause() {
		super.onPause();

		SharedPreferences.Editor ed = mPrefs.edit();
		ed.putInt("view_mode", mCurViewMode);
		ed.commit();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值