android.app.Activity---中文

Android.app.Activity

Activity是用户主要也是唯一打交道的途径。基本上所有的Activity都是和用户打交道的,你可以通过setContentView(View)来创建一个窗口。Activity常常是以全窗口的模式展示的,当然也有其他的展示方式:浮动窗口(windowIsFloating)或则嵌入到其他Activity(ActivityGroup)。基本上所有子类都会重写一下两个方法:

◆ onCreate(Bundle):初始化Activity。这里常会调用setContentView(int)来加载layout资源来定义你的UI,并且使用findViewById(int)来获取组件。

◆ onPause():指离开Activity时候触发的方法。用户在组件上所做的变更都要提交(通常保存到ContentProvider)

如果有调用Activity.startActivity(),必须在AndroidManifest.xml文件中的<activity>标签中声明该Activity。

Activity在整个应用的生命周期中起至关重要的作用。

Activity Lifecycle

系统中的Activity可以通过一个activity栈来进行管理。当一个新的activity启动的时候,它首先会被放置在activity栈顶部并成为running状态的activity —— 之前的activity也在activity栈中,但总是被保存在它的下边,只有当这个新的activity退出以后之前的activity才能重新回到前景界面

所有的activity有四中状态

◆ 如果activity在屏幕前端(在堆栈栈顶),那么这个activity是运行的

◆ 如果一个activity失去焦点时仍然可见(指新打开的activity不占用整屏),那么它的状态是paused。Paused 的Activity仍然可见(依然保存它的数据和状态信息,并且仍然由window manager ),但是会在系统处于低内存状态时候被清除。

◆ 如果一个Activity被其他activity覆盖时,它将处于stopped状态。它仍然保留数据和状态信息,但是它对于用户是不可见的。但是它会在系统其他地方需要内存的时候被杀掉

◆ 如果一个Activity处于paused或则stopped状态时,系统可以通过关闭或则杀掉进程的方式来释放它占用的内存。当再次需要它的时候,系统会重新启动并加载之前的状态。

下图是Activity的主要状态图:

对于你的activity,有三个点比较关键:

◆ Activity的整个生命周期从onCreate(Bundle)到onDestory().activity会在onCreate()时候创建所有的全局状态并且会在onDestory()时候释放这些资源。比如如果需要一个Thread在后台下载网络上的资源,那么需要在onCreate(Bundle)时候创建它并且在onDestory()时候释放它。

◆ Activity可见生命周期从onStart()到onStop().这个时间我们可以在屏幕上看到这些组件,尽管可能这个组件不在最前端。这两个方法之间可以调用一些展示给用户看的资源。比如可以在onStart()是创建一个BroadcastReceiver来接收对用户界面有影响的信息,在onStop()时候关闭它,那么在每次调用onStart()和onStop()时候都会穿件这个BroadcastReceiver。

◆ Activity的前景生命周期从onResume()到onPause()之间。这期间Activity处于和用户交互阶段。Activity会不断的在resume和pause状态之间切换:设备进入睡眠、activity需要的结果已传递过来了或则新的intent到达时。所以这两个方法应该是轻量级的。

Activity在整个生命周期中定义了以下方法,这些方法是以hook的形式定义的,你可以在子类中重写他们,一般来说子类都要覆盖onCreate(Bundle)来初始化一些数据而重写onPause()来提交用户的数据。一般会在最后调用父类的构造函数

Configuration changes

如果配置信息更改(在Resources.Configuration 类中定义),那么任何在用户界面定义的信息都会改变。由于activity是用来处理和用户交互的,所以它也提供了特别的机制来更新配置信息。除非你特别指定,否则配置的更改(比如屏幕的排序,语言,输入设备等)会导致当前的activity被destory,这里的destory是通过正常途径(通过生命周期的onPause(),onStop()以及onDestory()).如果activity正在展示给用户,那么当onDestory()调用时,会创建一个新的activity,并且前面那个示例中在onFreeze(Bundle)保存的内容传递给新的示例。因为任何资源都可能发生变化,所以最好的方法去处理配置的更改途径就是重新检索所有的资源(包括layouts、drawables、strings)。因为activity已经知道他们当前的状态,因而重新创建时一件很轻量的过程。在一些特殊的情况下,你可能希望当一种或则多种配置文件变化的时候不重启你的activity。你可以同坐在manifest文件中设置android:configchanges属性来是实现这一点。你可以在这里申明activity可以处理的任何配置变化,当这些变化发生时候不会重新启动activity而是调用activity的onConfigurationChanged(Resouces.configuration)方法。如果改变的配置中包含了你无法处理的配置(android.configChanges未申明),你的activity仍然会被重启而onConfigurationChanged(Resources.Configuration)将不会被调用。

Starting Activities and Getting Results

startActivity(Intent)是用来启动一个Activity的,也就是把这个Activity推到栈顶。它有一个唯一的参数,这个参数是用于描述要执行的Activity的。有时候你希望当一个Activity结束时可以返回一些信息。比如,你提供了一个Activity给用户选择电话薄,并希望在用户选择完后会返回选择的电话信息。你可以调用startActivityForResult(Integer,int)来启动Activity,第二个参数int就用来标示你想要返回的结果,通过调用onActivityResut(int,int,Intent)来获取返回的信息,第一个int就是你标识的。当activity退出时,可以调用setResult(int)来把数据返回给她的父进程。返回的结果码可以使标准结果RESULT_CANCELED,RESULT_OK,也可以是从RESULT_FIRST_USER定义的值,当然还可以是一个URL地址(通常是activity所希望的Bundle)。这些信息以及一些最初定义的值都会在父activity的Activity.onActivityResult()中出现。如果子Activity失败了(例如crashing),父Activity就会受到一个RESULT_CANCELED的结果。

这里有一个启动并处理结果的Activity:

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) {
// When the user center presses, let them pick a contact.
startActivityForResult(
new Intent(Intent.ACTION_PICK,
new Uri("content://contacts")),
PICK_CONTACT_REQUEST);
return true;
}
return false;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// A contact was picked. Here we will just display it
// to the user.
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}
}

Saving Persistent Sate

Activity会处理两类的持久状态:共享文档类数据(通过contesnt provide共享的保存在SQLite数据)以及内部状态(例如用户自定义数据)

对于content provider的数据,我们建议activity使用“编辑即发生”用户模型。就是说,用户所做的任何编辑都将立即生效而不要求任何进一步的确认。下面两条规则可以使支持这种模型成为一件简单的事情。

◆创建一个新文档的时候,立即为它创建文件或者后台数据库条目。举例来说,如果用户要写一封新邮件,当他们开始输入的时候马上创建一个新的数据库条目,所以即使他们输入以后进入别的activity,这封邮件也会在草稿箱中出现。

◆当activity的onPause()方法被调用时,它应该将任何用户所做修改向后台的content provider 或者文件提交。这可以确保即将运行的其他activity可以看到这些修改。你可能会使用更激进的方式来在你的activity生命周期中关键的时间点上提交数据:例如在启动一个新的activity之前、终止你的activity之前、当用户在输入域之间切换时,等等。

这个模型是为了避免用户在activity之间切换时数据丢失而设计的,同时允许系统在activity处于paused状态后任何时间都可以安全的kill这个activity(因为其它地方可能需要系统资源)。注意这隐含着一个含义,即用户点击你activity的BACK键并不意味着“取消”——它意味着保存他当前的内容并离开你的activity。Activity中取消编辑必须通过其他机制来提供,例如显式的提供"revert" 或 "undo"选项。

Activity同时提供了API来管理与activity相关联的内部持久状态。这可以用来记忆用户日历的首选初始显示(日期视图或者周视图)或者用户web浏览器的缺省主页这类信息。

Activity持久状态使用getPreferences(int)方法来管理,允许你取得和修改一系列与activity相关联的名称/取值对。如果要在应用的多个组件(activities,recivers,services,providers)之间共享参数,你可以使用底层方法Context.getSharedPreferences()来获得存储在一个特定名称下的参数对象。(注意:在application packages之间不能共享设置数据 —— 如果要这么做的话你需要使用content provider)。

这里摘录了一段日历activity中的代码,用来在永久设定中保存用户首选的视图模式。

1: public class CalendarActivity extends Activity { 2: ... 3: static final int DAY_VIEW_MODE = 0; 4: static final int WEEK_VIEW_MODE = 1; 5: private SharedPreferences mPrefs; 6: private int mCurViewMode; 7: 8: protected void onCreate(Bundle icicle) { 9: super.onCreate(icicle); 10: SharedPreferences mPrefs = getSharedPreferences(); 11: mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE); 12: } 13: 14: protected void onPause() { 15: super.onPause(); 16: SharedPreferences.Editor ed = mPrefs.edit(); 17: ed.putInt("view_mode", mCurViewMode); 18: ed.commit(); 19: } 20: }Permissions
你可以通过在Activity所属应用的manifest文件中对应的<activity>标签中进行声明来限制哪些应用可以启动此Activity。如果你进行了声明,其它应用需要在他们自己的manifest文件中声明对应的<uses-permission>元素(而且需要在安装时被授予许可:译者注)才可以启动这个activity。

Process Lifecycle
Android系统会尽量久的保留应用进程。但是当内存降低时最终还是要移除旧的进程。就像Activity 生命周期 中描述的一样,移除哪个进程还是要取决于关联的用户与之交互的程度。一般来说,进程可以基于其中运行的activity所处的生命周期而分成四种状态,下面将这些状态根据重要程度排列。系统会在kill更重要的进程(第一个)之前首先kill那些不那么重要的进程(最后一个)。

◆前景activity(处于屏幕最上方,用户与之交互的activity)被认为是最重要的。如果设备上的内存无法满足它的使用,Kill此进程只能作为最后的手段。一般来说这个时候设备处于内存paging状态,为了使用户界面保持响应才会发出这个kill请求。

◆可见activity(一个对用户可见,但是不在前景的activity,比如处在浮动对话框后)被认为是非常重要的,除非为了保证前景activity运行,否则不会被kill。

◆后台activity(一个对用户不可见,并处于paused状态的activity)就不再重要了,所以◆空进程是一个没有运行activity或者其他应用组件(比如Service或者IntentReceiver类)的进程。当内存开始降低时系统很快就会kill掉这些进程。因此当你要在activity外运行任何的后台操作时,必须在IntentReceiver或Service的上下文环境中运行,这样系统才知道需要将你的进程保留而不是kill。

有些时候Activity可能需要长时间运行一个操作,且它并不依赖于activity的生命周期而存在。例如一个照相机应用可能允许你将照片上传到web站点。上传可能需要很长时间,在上传过程中应该允许用户离开这个应用。为了做到这一点,你的activity应该在上传时启动一个Service来执行此工作。这将使系统在你的进程上传数据的过程中能够恰当的区分它的优先级(认为此进程比其他不可见应用更重要),不管原来的activity的状态是paused、stopped还是finished。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/timchen6824/archive/2011/03/08/6231470.aspx

你可能感兴趣的:(Activity)