——本文来自博客园Tekkaman的博客Android之Activity IBM的developerWorks网站张勇详解Android的Activity组件一文 ,CSDN博客hpoi的博客Android Activity的生命周期 感谢zzxap在CSDN论坛的自问自答——安卓工程运行是如何指定初始页面的droid工程运行是如何指定初始页面的

Activity

activity类处于android.app包中,继承体系如下:

1.java.lang.Object

2.android.content.Context

3.android.app.ApplicationContext

4.android.app.Activity

activity是单独的,用于处理用户操作。几乎所有的activity都要和用户打交道,所以activity类创建了一个窗口,开发人员可以通过setContentView(View)接口把UI放到activity创建的窗口上,当 activity指向全屏窗口时,也可以用其他方式实现:作为漂浮窗口(通过windowIsFloating的主题集合),或者嵌入到其他的 activity(使用ActivityGroup)。大部分的Activity子类都需要实现以下两个接口:

  • onCreate(Bundle)接口是初始化activity的地方. 在这儿通常可以调用setContentView(int)设置在资源文件中定义的UI, 使用findViewById(int) 可以获得UI中定义的窗口.

  • onPause()接口是使用者准备离开activity的地方,在这儿,任何的修改都应该被提交(通常用于ContentProvider保存数据).

为了能够使用Context.startActivity(),所有的activity类都必须在AndroidManifest.xml文件中定义有相关的“activity”项。

而对于安卓程序需要首先运行的activity即下文提到的“main”activity,则需要AndroidManifest.xml文件中的<intent-filter>元素添加这么两句:
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid: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方法的代码:
publicvoidonCreate(BundlesavedInstanceState){
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的生命周期的部分。

【Activity 的生命周期】

和 J2ME 的 MIDlet 一样,在 android 中,Activity 的生命周期交给系统统一管理。与 MIDlet 不同的是安装在 android 中的所有的 Activity 都是平等的。

*Activity 的状态及状态间的转换

在 android 中,Activity 拥有四种基本状态:

  1. Active/Runing一个新 Activity 启动入栈后,它在屏幕最前端,处于栈[关于Activity栈的概念,可见下文说明]的最顶端,此时它处于可见并可和用户交互的激活状态。

  2. Paused当 Activity 被另一个透明或者 Dialog 样式的 Activity 覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。

  3. Stoped当 Activity 被另外一个 Activity 覆盖、失去焦点并不可见时处于Stoped状态。

  4. KilledActivity 被系统杀死回收或者没有被启动时处于Killed状态。

当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作。下图说明了 Activity 在不同状态间转换的时机和条件:

图 1. 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。

*Activity 栈

Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示:

图 2. Activity 的状态与它在栈中的位置关系

如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 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();
}

这些方法的说明如下:

  1. protected void onCreate(Bundle savedInstanceState)一个 Activity 的实例被启动时调用的第一个方法。一般情况下,我们都覆盖该方法作为应用程序的一个入口点,在这里做一些初始化数据、设置用户界面等工作。大多数情况下,我们都要在这里从 xml 中加载设计好的用户界面。例如:

 setContentView(R.layout.main);

当然,也可从savedInstanceState中读我们保存到存储设备中的数据,但是需要判断savedInstanceState是否为null,因为 Activity 第一次启动时并没有数据被存贮在设备中:

 if(savedInstanceState!=null){ 
savedInstanceState.get("Key");
}

  1. protected void onStart()该方法在 onCreate() 方法之后被调用,或者在 Activity 从 Stop 状态转换为 Active 状态时被调用。

  2. protected void onResume()在 Activity 从 Pause 状态转换到 Active 状态时被调用。

  3. protected void onPause()在 Activity 从 Active 状态转换到 Pause 状态时被调用。

  4. protected void onStop()在 Activity 从 Active 状态转换到 Stop 状态时被调用。一般我们在这里保存 Activity 的状态信息。

  5. protected void onDestroy()在 Active 被结束时调用,它是被结束时调用的最后一个方法,在这里一般做些释放资源,清理内存等工作。

图 3. 这些方法的调用时机

此外,Android 还定义了一些不常用的与生命周期相关的方法可用:

 protected void onPostCreate(Bundle savedInstanceState); 
protected void onRestart();
protected void onPostResume();

Android 提供的文档详细的说明了它们的调用规则。

【创建一个 Activity】

在 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】

Activity.startActivity()方法可以根据传入的参数启动另外一个 Activity:

 Intent intent =new Intent(CurrentActivity.this,OtherActivity.class); 
startActivity(intent);

当然,OtherActivity同样需要在 AndroidManifest.xml 中定义。[关于intent的内容将在安卓之Activity信使——intent文中介绍






更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. Android(安卓)调用谷歌语音识别
  5. Android(安卓)CheckBox中设置padding无效问题解决方法
  6. android的Handler
  7. Android四大基本组件介绍与生命周期
  8. Android(安卓)WiFiDirect 学习(二)——Service Discovery
  9. unity与Android之间的简单交互

随机推荐

  1. 契约类相关的序列化与反序列化实例详解
  2. 关于Asp.Net Core MongoDB的实例代码
  3. C#中方向键与回车键切换控件焦点的两种方
  4. 详解如何通过反射获得枚举的Display中nam
  5. .net Elasticsearch入门实例详解
  6. C#简单工厂模式是什么?
  7. 分享一个“网红脸“”框架实例教程
  8. 本地是怎么配置iis调试的?
  9. 分享一些平时收藏和应用的开源代码
  10. pull总是提示输入密码问题是什么情况?