【Android Developers Training】 15. 启动一个Activity
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。
原文链接:http://developer.android.com/training/basics/activity-lifecycle/starting.html
不像其他的编程范例一样应用的函数入口是“main()”方法,Android根据Activity处于何种声明周期状态去调用它所对应的生命周期回调函数,以此来创建一个Activity实例。有一系列的生命周期函数用来启动一个Activity,与之对应的,也有一系列生命周期函数来销毁一个Activity。
这堂课将概要地讲解一些最重要的生命周期函数,然后向你展示如何处理第一个生命周期回调函数,这个函数用来创建一个Activity的实例。
一). 理解生命周期回调函数
在一个Activity的声明周期中,系统会调用一系列声明周期函数,就像是一个金字塔阶梯一样向上爬行。每一个声明阶段都是金字塔上的一个台阶。当系统创建了一个新的Activity实例,每个声明周期函数将Activity的状态向上移动一个阶段。在金字塔的顶端所对应的状态是Activity已经在前台同时获得了用户焦点。
当用户要离开这个Activity,系统会调用其他生命周期函数(延金字塔下行)以次来销毁Activity。在有些情况中,Activity会只下行一部分,然后等待(比如用户切换到了其他应用),之后Activity可以从这个状态再回到顶端(如果用户重新回到Activity),并且恢复到用户离开时的状态
图1. 一个关于Activity生命周期的简单描绘,我们用阶梯状金字塔来解释它,这个图展示了每个回调函数都会转移Activity的状态
根据你的Activity的复杂度,你可能不需要实现所有的声明周期函数。然而,你务必要理解每一个生命周期函数,并且在开发过程中,实现那些可以让你的应用表现出用户期望状态的那些函数。实现你的Activity生命周期函数可以在多个方面让你的应用表现出色,包括:
- 不会因为用户切换到另一个应用或者接了一个电话而崩溃
- 不会在用户不使用它时消耗太多系统资源
- 不会在用户离开应用再返回时,丢失使用进度
- 不会在用户切换屏幕方向时崩溃或丢失使用进度
随着你进一步学习,会有多种如图1中显示的Activity状态切换的情况。然而,只有这些状态中的3个是静态的。即,在一段时间内(非瞬时)Activity只能处于这三个状态中的一个。
恢复态(Resumed)
在这个状态,Activity在前台,并且用户可以和它交互(获得用户焦点),有些时候也称之为“运行态”
暂停态(Paused)
在这个状态,Activity有一部分被另一个Activity遮挡,也就是说,在前台的这个Activity是半透明的,或者是没有充满整个屏幕的。当Activity处于这个状态时,它不能接收用户的输入也不能执行任何代码。
停止态(Stopped)
在这个状态,Activity被完全地隐藏,无法被用户看见,也可以理解为处于后台。当处于停止态时,Activity的实例以及它的状态信息,(如:成员变量)会被保留,这样就能马上使Activity转移到恢复态。
二). 指定你的启动Activity
当用户在主页面点击了你的应用图标,系统会调用你在应用中声明的启动(launcher)Activity,(可理解为“main”)的onCreate()方法。这个Activity就是你的应用和用户交互的主入口。
你可以在清单文件中定义哪个Activity作为入口Activity,AndroidManifest.xml文件在你的项目工程的根目录下。
你的应用的入口Activity必须在清单文件中使用<intent-filter>标签来声明,在标签中,具有MAIN行为(action),和LAUNCHER类别(category),例如:
<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>
Note:
当你使用Android SDK工具创建了一个新的Android项目工程,默认的项目文件会包含一个Activity,且它已在清单文件中拥有上述过滤器(filter)标签声明。
如果在你的Activity中,MAIN行为或者LAUNCHER类别任何一个没有声明,那么你的应用图标将不会在系统的主页面应用图标列表中出现。
三). 创建一个新的实例
大多数应用包含一些不同的Activity来让用户进行不同的操作。无论这个Activity是当用户点击应用图标时所启动的Activity,还是应用在对用户操作进行响应时启动的另一个Activity,系统通过调用onCreate()方法来创建每一个Activity实例。
你必须实现onCreate()方法来表现出基本的应用启动逻辑,这在该Activity整个生命周期中只发生一次。例如:你实现的onCreate()方法定义了用户接口,同时还可能实例化一些类作用域下的变量。
例如:下述例子中的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); } }
Caution:
使用SDK_INT这种方法可以避免老版本系统执行较新的API,但这种方法只适用于Android 2.0(API LEvel 5)及以上。比这再之前的系统会遇到一个运行时错误。
一旦onCreate()方法完成了执行,系统会紧接着调用onStart()和onResume()方法。你的Activity永远不会停留在创建态(Created)或启动态(Started)。从技术上说,当onStart()方法被调用后,activity对用户变成可见的,但是onResume()方法紧跟着执行,然后activity保持在恢复态(Resumed)直到某些事件发生改变了它,比如当有一个电话打来,或这个用户到了另一个activity,或者这个屏幕关闭了。
在后续的课程中,你将会看到其它用于启动的方法(onStart()和onResume()方法),在你的activity生命周期中是非常重要的,尤其在当activity处于暂停态或停止态时被调用用来恢复activity。
Note:
onCreate()方法包括一个叫做“savedInstanceState”的参数,在后续课程(Recreating an Activity)将会对其讨论。
图2. 图中方框包括当创建一个新的activity实例时的三个回调方法:onCreate(),
onStart()和
onResume()。
一旦这一系列回调函数执行完毕,activity到达了恢复态,用户可与其交互,直到用户切换到了另一个activity。
四). 销毁Activity
Activity生命周期的第一个回调函数是onCreate(),最后一个回调函数式onDestroy()。当系统为activity调用这个方法后,就意味着activity实例从RAM中彻底被移除。
大多数应用不需要实现这个方法,因为本地类引用会随着activity被销毁,并且你的activity会在onPause()方法和onStop()方法中执行大多数的清除工作。然而,如果你的activity包含有在onCreate()中创建的后台线程,或者其他会长时间运行的资源,不实现onDestroy()方法会导致内存泄露,所以你应该在onDestroy()中清除它们。
@Override public void onDestroy() { super.onDestroy(); // Always call the superclass // Stop method tracing that the activity started during onCreate() android.os.Debug.stopMethodTracing(); }
Note:
系统会在onPause()和onStop()方法执行后调用
onDestroy()方法。有一个情况例外:当你在
onCreate()方法中调用finish()方法。有一些这样的例子:比如当你的activity是一个零时的决策者,用来决定要启动哪一个activity。你可能会在onCreate()方法中调用finish()方法。在这种情况下,系统会马上调用onDestroy()方法,而不会调用任何其他的生命周期函数。