管理Activity的生命周期

管理Activity的生命周期

当一个用户导航通过、退出或回到你的app,你的app中的Activity实例在它们生命周期的不同状态之间进行转换。例如,当你的Activity第一次被启动,它来系统的前台并接受用户的关注。在这个过程,Android系统在Activity上调用了一系列的生命周期方法,在这个Activity中你设置好用户界面和其他组件。如果用户执行动作启动了另一个Activity或切换到另一个app,Android在你的Activity上调用另一组生命周期方法,因为它移到了后台(在这里Activity不再可见,但是实例和它的状态仍然是完整的)。

在生命周期回调函数中,你可以声明在用户离开和重新进入时你的Activity是如何行动的。举个例子,如果你正在构建一个流媒体视频播放器,当用户切换到另一个app时,你可能会暂停这个视频并终结网络连接。当用户回来时,你能重新连接网络并允许你的用户从同样的点重新开始播放。

这个课程介绍每个Activity实例接收到的重要的生命周期方法,以及你该如何使用它们,使你的Activity做用户所期望它做的,当你的应用程序不需要系统资源时不会消耗系统资源。

启动一个Activity

不像其他的编程范例,app通过main()方法进行加载,对应于Activity的生命周期的不同阶段,Android系统调用特定的回调方法来启动Activity实例的代码。这里有一系列的回调方法来启动一个activity,也有一系列的回调方法来效果一个Activity。

这一课提供一个最重要的生命周期方法的概况,当创建一个你的Activity的实例是,告诉你如何应对第一个生命周期方法。

理解生命周期回调方法

在Activity的整个生命周期中,系统会按顺序调用一系列核心的生命周期方法,就像一个阶梯金字塔。也就是,Activity生命周期的每一个阶段就是金字塔的一个阶梯。当系统创建一个Activity实例,每一个回调方法将Activity的状态向顶端移动一步。金字塔的顶端就是Activity在前端运行并且能够和用户进行交互的点。

当用户开始离开这个Activity,系统调用另外的方法,将Activity的状态向下移到金字塔的底端,从而可以取消这个Activity。在某些情况下,Activity会只向下移动金字塔的一部分并等待(例如用户切换到其他的App),从这个点Activity可以重新移回顶端(如果用户返回到这个Activity),从用户离开的地方重新开始。


 根据你的Activity的复杂程度,你可能并不一定需要实现所有的生命周期方法。但是,有一点很重要,你要理解每个方法并实现它们,你的app的表现方式和用户期待的一样。恰当的实现你的Activity的生命周期方法,可以确保在以下几方面表现良好,包括:

  • 当使用你的app时接到了一个电话或切换到另一个app时不会崩溃。
  • 当用户实际没有在使用它时不会占用宝贵的系统资源。
  • 当用户离开你的App并在一段时间后又回来时,不会丢失用户的进度。
  • 当屏幕在横摆和直摆之间旋转时不会崩溃或丢失用户的进度。

正如你在后面课程中将学习到的,导致一个Activity在上图所示的不同状态之间转变的情况有很多。然而这其中只有三个状态是可以静止的。也就是说,一个Activity只能在这三个状态中的某一个存在一段时间。

  1. Resumed:在这个状态下,Activity在前台运行并且用户可以与其交互。(有时也称为运行状态)
  2. Paused:在这个状态下,Activity被一个另一个Activity部分掩盖——另一个在前台运行的Activity是半透明的或者没有覆盖整个屏幕。Paused状态的Activity不能接收用户输入,也不能执行任何代码。
  3. Stopped:在这个状态下,Activity被完全隐藏了,用户看不到它;这时它被认为在后台。当停止时,Activity实例和它的状态信息例如成员变量还是被保留着的,但是它不能执行任何代码。
其他的状态(Created和Started)都是瞬时的,系统通过调用下一个生命周期回调函数马上从它们转移到下一个状态。也就是,系统在调用onCreate()方法后,很快就调用onStart()方法,紧跟着又调用onResume方法。 这些是基本的Activity生命周期,现在你将学习一些特殊的生命周期行为。

指定你的app的加载Activity

 当用户在主屏幕选择你的图标时,系统调用你的app中声明为"launcher"或者"main"的Activity的onCreate()方法。这个activity是作为你的app用户界面的主入口的Activity。

你可以在Android manifest文件(AndroidManifest.xml)中定义哪个Activity作为你的main activity,这个文件在你的工程的根目录下。

你的app的main activity必须在manifest中声明,使用包含MAIN action和LAUNCHER category的<intent-filter>。例子如下:

<activity android:name=".MainActivity" android:label="@string/app_name">
     <intent-filter>
         <action android:name="android.intent.action.MAIN" />
         <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
</activity>

注意:当你使用Android SDK工具创建一个新的Android工程时,默认的工程文件会包含一个Activity类,这个Activity类会在manifest上用这个intent-filter定义。

如果你的某个activity没有用MAIN action或LAUNCHER category声明,则你的app的图标将不会出现在主屏幕的app列表中。

创建一个新实例

大多数app包含多个不同的Activity,从而允许用户执行不同的操作。不管这个Activity是用户点击app图标时自动创建的main activity,还是你的app为了响应用户的操作而启动的不同的activity,系统都是通过调用Activity的onCreate()方法创建每个Activity的新实例。

你必须实现onCreate()方法来执行基本的应用程序启动逻辑,这些动作在Activity的整个生命周期中只会发生一次。例如,你的哦你Create()方法的实现应该定义用户界面,也可以初始化一些类范围内的变量。

例如,如下例子的onCreate()方法展示了一些为activity执行一些基础设置的代码,比如声明用户界面(在XML布局文件中定义的),定义成员变量,设置部分UI。

TextView mTextView; // Member variable for text view in the layout  

@Override 
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     // Set the user interface layout for this Activity
     // The layout file is defined in the project res/layout/main_activity.xml file
     setContentView(R.layout.main_activity);
     
     // Initialize member TextView so we can manipulate it later
     mTextView = (TextView) findViewById(R.id.text_message);
     
     // Make sure we're running on Honeycomb or higher to use ActionBar APIs
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
         // For the main activity, make sure the app icon in the action bar
         // does not behave as a button
         ActionBar actionBar = getActionBar();
         actionBar.setHomeButtonEnabled(false);
     } 
}

 警告:使用SDK_INT这种方式来阻止老的系统执行新的API只能在Android2.0(API 5)及以上版本才行。来的版本会产生运行时异常。

一旦onCreate()方法执行结束,在成功后系统很快调用onStart()和onResume()方法。你的Activity从不会存在于Created或Started状态。技术上来说,当onStart()方法被调用时,Activity已经变得可见了,但是onResume()方法很快就被调用了并且activity保持在Resumed状态直到发生了某些事情来改变它,例如接到了一个电话,用户导航到另一个Activity或者设备的屏幕关闭了。

在后续的其他课程中,你将看到其他的启动方法onStart()和onResume(),在你的activity的生命周期中很有用,当从Paused或Stopped状态重新启动activity时。

注意:onCreate()方法包括一个参数savedInstanceState,这将会在后面的课程重新创建Activity中讨论。


 

销毁Activity

Activity生命周期的第一个回调函数是onCreate(),它的最后一个回调函数onDestroy()。系统在你的Activity上调用这个回调函数作为最终的信号,通知你你的Activity实例将会被完全移出系统内存中。

大多数app都不需要实现这个方法,因为本地类引用(local class reference)和activity一起被销毁,并且你的activity应该在onPause()和onStop()方法中执行大多数的清理动作。然而,如果你的activity包括在onCreate()方法中创建的后台线程或者其他长时间运行的如果不正确关闭可能导致内存泄露的资源的话,你应该在onDestroy()方法中杀掉它。

@Override public void onDestroy() {
     super.onDestroy();  // Always call the superclass
     
     // Stop method tracing that the activity started during onCreate() 
    android.os.Debug.stopMethodTracing(); 
}

 注意:系统会在已经调用onPause()和onStop()方法后调用onDestroy()方法,除了一种情况:当你在onCreate()方法中执行finish()方法时。在某些情况下,比如你的activity作为临时决策者去启动另一个activity,你也许会在onCreate()方法中调用finish()方法销毁这个activity。在这种情况下,系统直接调用onDestroy方法,而不调用任何其它的生命周期方法。

猜你喜欢

转载自jayceyxc.iteye.com/blog/2244157