学习一项技术,看官方文档无疑是最好的途径。而我写博客只是想将自己所学的总结分享一下。坚持一件事情需要很大的毅力显然我还没具备这些条件,但我觉得应该努力一下这样未来才能做一个更好的自己。
Android开发英文文档:http://android.xsoftlab.net/guide/components/index.html。
Android开发部分翻译文档:http://www.android-doc.com/guide/components/index.html。
Android包括四大组件分别为Activity(活动)、Service(服务)、Contentprovider(内容提供者)、BroadcastReceiver(广播接收者)。下面我总结的是关于Activity的知识点,其他的今后会在总结。
Activity是什么?
Activity是一种可以包含用户界面的程序组件,它为用户提供一个用于任务交互的画面。一个应用程序通常由一个或者多个activity组成,程序第一个展现在用户面前的就是在应用程序内部被指定为主的activity.
创建一个Activity
要创建一个activity需要创建一个Activity
(或者它存在的子类)的子类。 在你的子类里,你需要实现系统调用的回调方法,这些方法用于activity在生命周期中进行事务处理。其中有两个最重要的回调方法:
onCreate():系统会在创建activity的时候调用这个方法。在这个方法中实现你activity的重要组件。最重要的是,必须在这里调用setContentView()来定义你用于用户交互的布局。
onPause():系统将会调用这个方法作为用户离开activity的首次提示(虽然这并不意味着activity正在被销毁)。
为了可以访问activity需要在配置文件AndroidManifest中声明activity
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
启动一个Activity
为了展现不同的内容,每一个activity可以启动另外一个。 启动一个其他的activity通过调用startActivity()
, 并传递一个 Intent
, 它用于描述acitity。 intent指定了你想要启动的activity,或者指定了你想展现的动作(系统帮你选择合适的activity,它可能来自于其他的程序)。 intent也可以携带比较小量的数据,用于启动acitivity。例如启动一个叫SignInActivity
的activity:
Intent intent = new Intent(this,SignInActivity.class);
startActivity(intent);
Intent intent = new Intent(Intent.ACTION_SEND);
//EXTRA_EMATL是一个邮件intent中添加指定了邮件该发给哪些邮件地址附带的字符串数组
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
有时候,你想要启动一个activity,并从这个activty获得一个结果。 这时,要通过 startActivityForResult()
(取代startActivity()
) 来启动activity。 然后通过实现onActivityResult()
回调方法来获得返回后的结果。 当这个后续的activity被关闭,它将发送一个 Intent
给 onActivityResult()
方法。例如取一个联系人的信息:
private void pickContact() {
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// 判断请求是否被成功响应, 然后判断这个响应是不是针对相应的请求
if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
// 查询 Intent中的data信息
Cursor cursor = getContentResolver().query(data.getData(),
new String[] {Contacts.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
String name = cursor.getString(columnIndex);
}
}
}
关闭Activity
你可以通过调用finish()
来终止activity。 你也可以调用finishActivity()
来终止你之前启动了的一个独立activity。
注意: 多数情况下,你不应该明确地通过这些方式来关闭acitivity。 就像下面要讨论的activity的生命周期。系统会为你管理。所以你不必关闭他们。 调用这些方法将有悖于用户体验。它们仅用于你绝对不想让用户再返回这个activity的实例。
Activity的生命周期
相信看完上面相信你对activity已有一定的了解了,下面我们继续讨论activity的生命周期。
其实Android是使用任务(Task)来管理活动的, 每当一个新的activity被启动,那么之前的将被停止。但系统将会把它压入一个栈(“Back Stack”即后退栈),当一个新的activity启动,它将被 放到栈顶并获得用户焦点。后台栈遵循后进先出的栈机制。所以当用户完成当前页面并按下返回按钮时,它将被pop出栈(并销毁),之前的activity将被恢复。如图
通过实现回调方法来管理你的activity的生命周期,对于开发一个健壮而又灵活的应用程序而言是至关重要的。
Activity可能处四种基本的状态:
Resumed(运行状态):activity在屏幕的前台并且拥有用户的焦点。此时活动处于运行状态,位于返回栈的栈顶。
Paused(暂停状态):另一个activity在前台并拥有焦点,但是本activity还是可见的。 也就是说,另外一个activity覆盖在本activity的上面,并且那个activity是部分透明的或没有覆盖整个屏幕。 一个paused的activity是完全存活的,但在系统内存严重不足的情况下它能被杀死。
Stopped(停止状态):本activity被其它的activity完全遮挡住了(本activity目前在后台)。 一个stopped的activity也仍然是存活的。但是,对于用户而言它已经不再可见了,并且当其它地方需要内存时它将会被杀死。
Destroy(销毁状态):本activity被从返回栈中移除,这种状态易被杀死从而保证内存的充足。
activity生命周期回调方法汇总:
方法 | 描述 | 之后 是否 杀死 | 下一个方法 |
onCreate() | activity第一次被创建时调用。 在这里你应该完成所有常见的静态设置工作—— 创建view、绑定list数据等等。 本方法传入一个包含了该activity前一个状态的Bundle对象, 下一个回调方法总是onStart()。 | 否 | onStart() |
onRestart() | activity被停止后、又再次被启动之前调用。 下一个回调方法总是onStart() | 否 | onStart() |
onStart() | activity要显示给用户之前调用。 如果activity进入前台,则下一个回调方法是onResume(); 如果进入隐藏状态,则下一个回调方法是onStop()。 | 否 | onResume() 或者 onStop() |
onResume() | activity开始与用户交互之前调用。 这时activity是在activity栈的顶端,用户可以向其中输入。 下一个回调方法总是onPause()。 | 否 | onPause() |
onPause() | 当系统准备启动另一个正在恢复的activity时调用。 这个方法通常用于把未保存的改动提交为永久数据、停止动画播放、 以及其它可能消耗CPU的工作等等。 它应该非常迅速地完成工作, 因为下一个activity在本方法返回前是不会被恢复运行的。 如果activity返回前台,则下一个回调方法是onResume(); 如果进入用户不可见状态,则下一个是onStop() | 是 | onResume() 或者 onStop() |
onStop() | 当activity不再对用户可见时调用。 原因可能是它即将被销毁、或者 其它activity(已有或新建的)被恢复运行并要覆盖本activity。 如果activity还会回来与用户交互,则下一个回调方法是onRestart(); 如果这个activity即将消失,则下一个回调方法是onDestroy() | 是 | onResume() 或者 onDestroy() |
onDestroy() | 在本activity被销毁前调用。 这是activity收到的最后一个调用。 可能是因为activity完成了工作(有些人在这里调用finish()), 也可能是因为系统为了腾出空间而临时销毁activity的本实例。 可以利用isFinishing() 方法来区分这两种情况。 | 是 | 无 |
注:标为“之后是否杀死”的列指明了系统是否可以在这个方法返回之后的任意时刻杀掉这个activity的宿主进程, 而不再执行其它流程上的activity代码。
总体来讲,这些方法定义了一个activity的完整的生命周期。 通过实现这些方法,你可以监控activity生命周期中三个嵌套的循环:
完整生存期:在 onCreate() 调用和 onDestroy() 调用之间发生。 你的activity应该在 onCreate() 方法里完成所有“全局global”状态的设置(比如定义layout), 而在onDestroy() 方法里释放所有占用的资源。
可见生存期:在 onStart() 调用和 onStop() 调用之间发生。在这期间,用户可在屏幕上看见这个activity并可与之交互。
前台生存期:在 onResume() 调用和 onPause() 之间发生。在这期间,activity是位于屏幕上所有其它的activity之前,并且拥有用户的输入焦点。因为这个状态可能会经常发生转换,为了避免切换迟缓引起的用户等待,这两个方法中的代码应该相当地轻量化。
保存Activity的状态
Activity 对象在paused或者stopped时仍然被保留在内存之中——它所有的成员信息和当前状态都仍然存活。 这样用户在activity里所作的改动全都还保存着。
不过,如果系统是为了回收内存而销毁activity,则这个 Activity 对象就会被销毁,这样系统就无法简单地resume一下就能还原完整状态的activity。为了保证activity状态的相关重要信息都由另一个回调方法保存下来了,调用
onSaveInstanceState()来保存activity状态的相关信息。
调用时系统会传入一个Bundle对象, 你可以利用 putString() 之类的方法,以键值对的方式来把activity状态信息保存到该Bundle对象中。 然后,如果系统杀掉了你的application进程并且用户又返回到你的activity,系统就会重建activity并将这个 Bundle 传入onCreate() 和onRestoreInstanceState() 中,你就可以从 Bundle 中解析出已保存信息并恢复activity状态。如果没有储存状态信息,那么传入的 Bundle 将为null(当activity第一次被创建时就是如此)。
activity状态完整地返回给用户的两种方式:被销毁destroyed后再被重建,而且必须恢复了之前保存的状态;或是被停止stopped后再被恢复resumed,状态都完整保留着。
注意:因为 onSaveInstanceState() 并不保证每次都会被调用,所以你应该只用它来记录activity的一些临时状态信息(UI的状态)——千万不要用它来保存那些需要长久保存的数据。 替代方案是,你应该在用户离开activity的时候利用 onPause() 来保存永久性数据(比如那些需要存入数据库里的数据)。
关于Activity这部分基本写完了,还有许多地方可能没有那么完善,不过希望这些能给你一些帮助。你的努力只为未来能做一个更好的自己。