——本文来自博客园Tekkaman的博客Android之Activity ,IBM的developerWorks网站张勇的详解Android的Activity组件一文 ,CSDN博客hpoi的博客Android Activity的生命周期 ,感谢zzxap在CSDN论坛的自问自答——安卓工程运行是如何指定初始页面的droid工程运行是如何指定初始页面的前端
activity类处于android.app包中,继承体系以下:java
1.java.lang.Objectandroid
2.android.content.Context程序员
3.android.app.ApplicationContext数据库
4.android.app.Activity网络
activity是单独的,用于处理用户操做。几乎全部的activity都要和用户打交道,因此activity类建立了一个窗口,开发人员能够经过setContentView(View)接口把UI放到activity建立的窗口上,当 activity指向全屏窗口时,也能够用其余方式实现:做为漂浮窗口(经过windowIsFloating的主题集合),或者嵌入到其余的 activity(使用ActivityGroup)。大部分的Activity子类都须要实现如下两个接口:app
onCreate(Bundle)接口是初始化activity的地方. 在这儿一般能够调用setContentView(int)设置在资源文件中定义的UI, 使用findViewById(int) 能够得到UI中定义的窗口.ide
onPause()接口是使用者准备离开activity的地方,在这儿,任何的修改都应该被提交(一般用于ContentProvider保存数据).函数
为了可以使用Context.startActivity(),全部的activity类都必须在AndroidManifest.xml文件中定义有相关的“activity”项。网站
而对于安卓程序须要首先运行的activity即下文提到的“main”activity,则须要AndroidManifest.xml文件中的<intent-filter>元素添加这么两句:
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<action>元素指定这是一个"main"入口点对这个应用程序。<category>元素指定,这个activity应该被列入系统应用程序列表中(为了容许用户启动这个activity)。
若是你但愿应用程序自包含,而且不但愿别的应用程序激活它的activities,那么你不须要任何其它intent filters。只有一个activity应该有“main"动做和”launcher“分类,就像前面这个例子。你不但愿被其它应用程序访问原Activities应该没有intent filters并且你能启动他们经过本身显示的intent。
但是,若是你但愿你的activity响应影含的intents,从其它应用程序(和你本身的),那么你必须为这个activity定义额外的intent filters。每一种你但愿响应的类型的intent,你必须包含<intent-filter>,包含<action>元素,可选的,一个<category>元素而且/或一个<data>元素。这些元素指定你的activity能响应的intent的类型。
[若是全部的activity都包含此过滤器(即上面的filter),则默认首个activity为初始activity]
过滤器使用的具体过程参见如下描述,可帮助记忆和理解:
当写好的应用发布到手机上以后,当双击”抽屉“里该应用的图标时,系统会将这个点击时间包装成一个Intent,该Intent包含两个参数,如上所述的两个参数被传递给应用以后,在应用的功能清单文件中寻找与该意图匹配的意图过滤器,若是匹配成功,找到相匹配的意图过滤器所在的Activity元素,再根据<activity>元素的”name“属性来寻找其对应的Activity类。接着Android操做系统建立该Activity类的实例对象,对象建立完成以后,会执行到该类的onCreate方法,此onCreate方法是重写父类Activity的onCreate方法而实现的。onCreate方法用来初始化Activity实例对象。以下是helloWorld.java类中的onCreate方法的代码:
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
其中super.onCreate(savedInstanceState)的做用是调用其父类Activity的onCreate方法来实现对界面的图画绘制工做。在实现本身定义的Activity子类的onCreate方法时必定要记得调用该方法,以确保可以绘制界面。
setContentView(R.layout.main)的做用是加载一个界面。该方法中传入的参数是”R.layout.main“,其含义为R.java类中静态内部类layout的静态常量main的值,而改值是一个指向res目录下的layout子目录下的main.xml文件的标识符。所以表明着显示main.xml所定义的画面
一个Activity是一个应用程序组件,提供一个屏幕,用户能够用来交互为了完成某项任务,例如拨号、拍照、发送email、看地图。每个activity被给予一个窗口,在上面能够绘制用户接口。窗口一般充满屏幕,但也能够小于屏幕而浮于其它窗口之上。
一个应用程序一般由多个activities组成,他们一般是松耦合关系。一般,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity。每个activity而后能够启动另外一个activity为了完成不一样的动做[该动做经过intent完成,详见安卓之Activity信使——intent文]。每一次一个activity启动,前一个activity就中止了,可是系统保留activity在一个栈上(“back stack”)。当一个新activity启动,它被推送到栈顶,取得用户焦点。Back Stack符合简单“后进先出”原则,因此,当用户完成当前activity而后点击back按钮,它被弹出栈(而且被摧毁),而后以前的activity恢复。
当一个activity因新的activity启动而中止,它被通知这种状态转变经过activity的生命周期回调函数。有许多回调函数一个activity可能会收到,源于它本身的状态变化-不管系统建立它、中止它、恢复它、摧毁它-而且每一个回调提供你完成适合这个状态的指定工做的机会。例如,当中止的时候,你的activity应该释听任何大的对象,例如网络数据库链接。当activity恢复,你能够从新得到必要的资源和恢复被中断的动做。这些状态转换都是activity的生命周期的部分。
和 J2ME 的 MIDlet 同样,在 android 中,Activity 的生命周期交给系通通一管理。与 MIDlet 不一样的是安装在 android 中的全部的 Activity 都是平等的。
在 android 中,Activity 拥有四种基本状态:
Active/Runing一个新 Activity 启动入栈后,它在屏幕最前端,处于栈[关于Activity栈的概念,可见下文说明]的最顶端,此时它处于可见并可和用户交互的激活状态。
Paused 当 Activity 被另外一个透明或者 Dialog 样式的 Activity 覆盖时的状态。此时它依然与窗口管理器保持链接,系统继续维护其内部状态,因此它仍然可见,但它已经失去了焦点故不可与用户交互。
Stoped 当 Activity 被另一个 Activity 覆盖、失去焦点并不可见时处于 Stoped状态。
Killed Activity 被系统杀死回收或者没有被启动时处于 Killed状态。
当一个 Activity 实例被建立、销毁或者启动另一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动做。下图说明了 Activity 在不一样状态间转换的时机和条件:
如上所示,Android 程序员能够决定一个 Activity 的“生”,但不能决定它的“死”,也就时说程序员能够启动一个 Activity,可是却不能手动的“结束”一个 Activity。当你调用 Activity.finish()方法时,结果和用户按下 BACK 键同样:告诉 Activity Manager 该 Activity 实例完成了相应的工做,能够被“回收”[ 根据下文的意思,应该是调用finish方法时只能使Activity进入Stoped状态 ]。随后 Activity Manager 激活处于栈第二层的 Activity 并从新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态。例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当咱们调用 Activity2.finish()方法时,Activity Manager 从新激活 Activity1 并入栈,Activity2 从 Active 状态转换 Stoped 状态,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2 返回的数据经过 data参数返回给 Activity1。
Android 是经过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 老是在栈的顶端,当前台的 Activity 由于异常或其它缘由被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不一样状态间的转换。Activity 的状态与它在栈中的位置关系以下图所示:
如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。
在 android.app.Activity类中,Android 定义了一系列与生命周期相关的方法,在咱们本身的 Activity 中,只是根据须要复写须要的方法,Java 的多态性会保证咱们本身的方法被虚拟机调用,这一点与 J2ME 中的 MIDlet 相似。
public class OurActivity extends Activity {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
这些方法的说明以下:
protected void onCreate(Bundle savedInstanceState)一个 Activity 的实例被启动时调用的第一个方法。通常状况下,咱们都覆盖该方法做为应用程序的一个入口点,在这里作一些初始化数据、设置用户界面等工做。大多数状况下,咱们都要在这里从 xml 中加载设计好的用户界面。例如:
setContentView(R.layout.main);
固然,也可从 savedInstanceState中读咱们保存到存储设备中的数据,可是须要判断 savedInstanceState是否为 null,由于 Activity 第一次启动时并无数据被存贮在设备中:
if(savedInstanceState!=null){
savedInstanceState.get("Key");
}
protected void onStart()该方法在 onCreate() 方法以后被调用,或者在 Activity 从 Stop 状态转换为 Active 状态时被调用。
protected void onResume()在 Activity 从 Pause 状态转换到 Active 状态时被调用。
protected void onPause()在 Activity 从 Active 状态转换到 Pause 状态时被调用。
protected void onStop()在 Activity 从 Active 状态转换到 Stop 状态时被调用。通常咱们在这里保存 Activity 的状态信息。
protected void onDestroy()在 Active 被结束时调用,它是被结束时调用的最后一个方法,在这里通常作些释放资源,清理内存等工做。
此外,Android 还定义了一些不经常使用的与生命周期相关的方法可用:
protected void onPostCreate(Bundle savedInstanceState);
protected void onRestart();
protected void onPostResume();
Android 提供的文档详细的说明了它们的调用规则。
在 android 中建立一个 Activity 是很简单的事情,编写一个继承自 android.app.Activity的 Java 类并在 AndroidManifest.xml声明便可。下面是一个为了研究 Activity 生命周期的一个 Activity 实例(工程源码见下载):
Activity 文件:
public class EX01 extends Activity {
private static final String LOG_TAG = EX01.class.getSimpleName();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.e(LOG_TAG, "onCreate");
}
@Override
protected void onStart() {
Log.e(LOG_TAG, "onStart");
super.onStart();
}
@Override
protected void onResume() {
Log.e(LOG_TAG, "onResume");
super.onResume();
}
@Override
protected void onPause() {
Log.e(LOG_TAG, "onPause");
super.onPause();
}
@Override
protected void onStop() {
Log.e(LOG_TAG, "onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.e(LOG_TAG, "onDestroy ");
super.onDestroy();
}
}
AndroidManifest.xml 中经过 <activity> 节点说明 Activity,将 apk 文件安装后,系统根据这里的说明来查找读取 Activity,本例中的说明以下:
<activity android:name=".EX01" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Activity.startActivity()方法能够根据传入的参数启动另一个 Activity:
Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
startActivity(intent);
固然,OtherActivity一样须要在 AndroidManifest.xml 中定义。[关于intent的内容将在安卓之Activity信使——intent文中介绍]