概述
Activity概述
声明:原文来至Android官方开发参考Activity Class Overview。水平有限,敬请谅解
http://developer.android.com/reference/android/app/Activity.html
Activity是Android系统提供的界面,所有和用户的交互都发生在这里(类似于windows的窗口)。Activity在创建时生成各种控件视图(View),这些视图负责具体功能,例如ListView。Activity通常使用全屏模式,也有浮动窗口模式(通过设置属性windowIsFloating)和嵌入模式(参见ActivityGroup)。
它的继承类通常要重载两个方法:
1> onCreate(Bundle)是初始化函数,在这里可以调用setContentView(int)方法来设置界面布局(layout),也可以通过findViewById(int)方法来获取其子控件。
2> onPause()是失去焦点后所调用的函数,重要的是应该在这里保存用户的输入,通常用ContentProvider暂存这些数据。
程序包(package)在AndroidManifest.xml文件中声明你要首先启动哪个Activity,Context.startActivity()会根据其中相应的<Activity>设置来启动。
Activity是Android应用程序生命周期的重要组成部分,它的运行和管理是整个系统基础之一,详细情况在应用程序原理中叙述。
提纲:
1.Activity生命周期
2.配置变化
3.Activity的启动和返回
4.保存数据(saving persistent state)
5.权限
6.应用程序生命周期
Activity生命周期
系统使用一个栈管理所有的Activity。Activity启动后总是被放置在管理栈的顶端,成为当前窗口。之前的最顶端窗口退居二线,排在管理栈的第二。如果当前窗口退出,排在管理栈第二位的窗口就成为最顶端的当前窗口。
Activity的状态基本可以归纳成四个:
活动窗口(active or running),屏幕最前端的窗口(即管理栈的最顶端),它可以拥有用户输入的焦点,或称为当前窗口。
已暂停窗口(paused),当一个窗口失去焦点却仍然可见(此时的活动窗口通常是非全屏或透明的),系统会先调用它的onPause()函数。已暂停窗口拥有较高的生存权,它里面的数据受到保护,仍然保持着和窗口管理器的关联。缺乏内存时,系统会首先结束掉其它低生存权的窗口,如果内存仍然不足,也会结束掉已暂定窗口。已暂停窗口是不安全的
已停止窗口(stopped),当一个窗口全完被其它窗口遮挡,变得不再可见,系统会先调用其onStop(),它就成为已停止窗口。已停止窗口也可以保持它的数据,但很容易被系统结束掉,所以也是不安全的。
已终结窗口,已暂停或已停止的窗口很容易被系统终结(finish),或者被系统直接杀掉(kill)。注意:资源释放一般在onDestory中执行,finish会执行它,kill则不会。所以kill是不安全的。已终结窗口要再次显示给用户,则必须再次创建窗口。
下图为Activity的状态图,方框代表可以重载的方法,有色的椭圆代表主要状态。
Activity的状态基本可以归纳成四个:
活动窗口(active or running),屏幕最前端的窗口(即管理栈的最顶端),它可以拥有用户输入的焦点,或称为当前窗口。
已暂停窗口(paused),当一个窗口失去焦点却仍然可见(此时的活动窗口通常是非全屏或透明的),系统会先调用它的onPause()函数。已暂停窗口拥有较高的生存权,它里面的数据受到保护,仍然保持着和窗口管理器的关联。缺乏内存时,系统会首先结束掉其它低生存权的窗口,如果内存仍然不足,也会结束掉已暂定窗口。已暂停窗口是不安全的
已停止窗口(stopped),当一个窗口全完被其它窗口遮挡,变得不再可见,系统会先调用其onStop(),它就成为已停止窗口。已停止窗口也可以保持它的数据,但很容易被系统结束掉,所以也是不安全的。
已终结窗口,已暂停或已停止的窗口很容易被系统终结(finish),或者被系统直接杀掉(kill)。注意:资源释放一般在onDestory中执行,finish会执行它,kill则不会。所以kill是不安全的。已终结窗口要再次显示给用户,则必须再次创建窗口。
下图为Activity的状态图,方框代表可以重载的方法,有色的椭圆代表主要状态。
这里有三个关键的回路
全部寿命(entire lifetime),在第一次调用onCreate(Bundle)函数和onDestory()函数之间的时间,值得注意的是,onDestory只会调用一次,onCreate则会调用多次。onCreate用来设置全局的数据,onDestory则用来释放全部资源。例如你要使用多线程在后台下载数据,你就应该在onCreate里创建这个线程,onDestory里销毁该线程。
可见寿命(visible lifetime),发生在一次onStart和相应的onStop函数之间,用户可以看见的窗体。不管它是不是最前面的,也不管它能否与用户交互,程序都必须照常操作各种资源。例如:你需要接收一些消息来更新界面,那么就应该在onStart里面注册BroadcastReceiver,并在onStop里注销它。界面可以显示隐藏多次,onStart和onStop也相应的执行多次。
前台寿命(foreground lifetime),发生在一次onResume和相应的onPause函数之间。这期间,窗口在最前台,拥有焦点,与用户交互。在系统休眠、窗体切换等操作中,onResume和onPause都会被频繁执行。因此,这里的代码应当是轻量级的。
全部寿命(entire lifetime),在第一次调用onCreate(Bundle)函数和onDestory()函数之间的时间,值得注意的是,onDestory只会调用一次,onCreate则会调用多次。onCreate用来设置全局的数据,onDestory则用来释放全部资源。例如你要使用多线程在后台下载数据,你就应该在onCreate里创建这个线程,onDestory里销毁该线程。
可见寿命(visible lifetime),发生在一次onStart和相应的onStop函数之间,用户可以看见的窗体。不管它是不是最前面的,也不管它能否与用户交互,程序都必须照常操作各种资源。例如:你需要接收一些消息来更新界面,那么就应该在onStart里面注册BroadcastReceiver,并在onStop里注销它。界面可以显示隐藏多次,onStart和onStop也相应的执行多次。
前台寿命(foreground lifetime),发生在一次onResume和相应的onPause函数之间。这期间,窗口在最前台,拥有焦点,与用户交互。在系统休眠、窗体切换等操作中,onResume和onPause都会被频繁执行。因此,这里的代码应当是轻量级的。
Activity的下面这些方法贯穿了整个生命周期,它们都可以重载,重载时应该执行一下父类的这个方法。通常,onCreate(Bundle)加入初始化代码,onPause打断用户输入和提交保存数据。
public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
}
在整个声明周期中,这些函数通常如下执行。
注意上表的“可销毁”列,当那些函数返回后,系统就有可能销毁进程,甚至不给进程执行任何代码的机会。因此,onPause的时候就应该保存用户输入。窗口失去焦点变成后台窗口前会调用onSaveInstanceState(Bundle)函数,这里可以保存一个Bundle信息,下一次再创建这个窗口,执行onCreate(Bundle)的时候,这个信息就会被传递过去。但是用户输入还是应该在onPause中保存,因为onSaveInstanceState(Bundle)并不能保证一定会被执行。
上表中那些“可销毁”为否的函数执行后,系统就不能销毁该窗口。要销毁它们,系统必须调用其它函数,把窗口变到“可销毁”状态。
上表中那些“可销毁”为否的函数执行后,系统就不能销毁该窗口。要销毁它们,系统必须调用其它函数,把窗口变到“可销毁”状态。
配置变化
设备的配置发生变化后,所有的用户界面都必须适应这个变化。Activity对此有专门的支持。
诸如屏幕朝向、语言环境、输入设备的变化,都会引起现有的窗口销毁,走完onPause,onStop,onDestroy的生命周期。当前窗口和可见窗口还会在销毁后再创建一个新的实例,这个实例适应新的配置,也继承了上一个实例保存下来的Bundle。
资源文件和配置有关,例如布局,所以配置变化后,最好重新载入布局、图片、字符串等资源文件。
某些特定的配置变化时,如果你不想重启Activity,manifest文件中的android:configChanges属性提供了这个设置,当指定的配置发生变化时,系统不会重启Activity,而是会调用onConfigurationChanged(Configuration)函数。android:configChanges属性指定之外的配置变化,仍然会引起Activity重启。
Activity的启动和返回
startActivity(Intent)方法用来启动Activity,并把它放在管理栈的顶端,参数Intent可以携带上一次运行遗留下来的信息。
当你关闭一个Activity时,可以获得它的返回值。例如从通讯录中选取一条用户信息。你可以使用startActivityForResult(Intent, int)启动一个Activity,第二个int参数是你自定义的标示。返回值会通过onActivityResult(int, int, Intent)传递回来。
Activity关闭时你可以使用setResult(int)来设置返回值,并提供一个返回代码,RESULT_CANCELED, RESULT_OK, 自定义的返回代码则必须从RESULT_FIRST_USER开始。你还可以提供一个Intent对象来包含更多信息。
如果子窗口运行失败(如崩溃),则会返回RESULT_CANCELED。
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) {
// 如果用户按中键,启动通讯录
startActivityForResult(
new Intent(Intent.ACTION_PICK,
new Uri("content://contacts")),
PICK_CONTACT_REQUEST);
return true;
}
return false;
}
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// 如果用户按中键,启动通讯录
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) {
// 选取成功,则显示详细
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}
}
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// 选取成功,则显示详细
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}
}
保存数据(saving persistent state)
Activity有两种持久数据:共享的文档类数据(如SQLite中保存的content provider数据)和私有数据(如用户选项)。
对于content provider数据,Activity最好使用"Edit in place"模式,该模式会及时的自动保存用户输入。
它提供了两个便利场景:
文档创建时,保存数据的后台入口或文件就同时生成了。例如,用户编写email,数据会及时地自动保存,即使编写动作被打断,你也会看到一份已保存的起草email,数据不会丢。
如果你在Activity的onPause里把用户输入提交给content provider来保存,输入内容会得到很好的保存,不管是在Activity切换的瞬间,还是用户粗暴的乱按键盘。
这个模式主要是为了防止数据丢失,即使是在切换窗体和系统回收内存终结进程时,该模式也能很好工作。注意,系统的返回键不是用来放弃输入的,而是返退到上一个Activity,要放弃输入应使用其它明显的操作。
Activity还提供保存私有数据的方法,例如浏览器首页设置、日历的显示方式。
getPreferences(int)方法可以用来得到这些选项设置,Context.getSharedPreferences() 则可以获得一些共享的选项设置。
下面的代码演示了如何保存日历显示设置。
public class CalendarActivity extends Activity {
...
static final int DAY_VIEW_MODE = 0;
static final int WEEK_VIEW_MODE = 1;
static final int WEEK_VIEW_MODE = 1;
private SharedPreferences mPrefs;
private int mCurViewMode;
private int mCurViewMode;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
SharedPreferences mPrefs = getSharedPreferences();
mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE);
}
mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE);
}
protected void onPause() {
super.onPause();
SharedPreferences.Editor ed = mPrefs.edit();
ed.putInt("view_mode", mCurViewMode);
ed.commit();
}
}
super.onPause();
SharedPreferences.Editor ed = mPrefs.edit();
ed.putInt("view_mode", mCurViewMode);
ed.commit();
}
}
权限
详见“安全与权限”
详见“安全与权限”
进程生命周期
Android系统尽可能的保证运行着的进程不被终结,仅当内存不足的时候才开始终结部分进程,来释放资源。进程的终结和它的Activity状态有关。一般来说有四类进程,系统首先终结重要性低的进程,下面按重要性从高到低的顺序来叙述:
前台进程(foreground),拥有前台窗口的进程是重要性最高的,如果它所需的内存超出设备能力也会被终结。此时为了响应用户界面,系统会达到内存分页状态。
可见进程(visible),拥有可见窗口的进程拥有次高重要性。
后台进程(background),不再可见的进程变得不再重要,系统容易终结这些进程,再次运行它时,系统重新创建它,此时会携带一个Intent参数,该参数会保存前次运行的信息。
空进程(empty),不再拥有Activity或其它组件(如:后台接收器BroadcastReceiver)的进程被认为是空进程,系统会很快终结它们。因此,如果你有窗体之外后台操作,请一定在诸如BroadcastReceiver等服务中运行,以便让系统知道该进程不能被终结。
有些时候你需要后台执行一些长时间运行的操作,比如上传视频,此时你应当注册一个后台服务来达到这个目的,并允许用户离开该进程的窗口。这样系统就能正确评价该进程的优先级,把它和那些不可见进程区分开来,不至于轻易终结它。
Android系统尽可能的保证运行着的进程不被终结,仅当内存不足的时候才开始终结部分进程,来释放资源。进程的终结和它的Activity状态有关。一般来说有四类进程,系统首先终结重要性低的进程,下面按重要性从高到低的顺序来叙述:
前台进程(foreground),拥有前台窗口的进程是重要性最高的,如果它所需的内存超出设备能力也会被终结。此时为了响应用户界面,系统会达到内存分页状态。
可见进程(visible),拥有可见窗口的进程拥有次高重要性。
后台进程(background),不再可见的进程变得不再重要,系统容易终结这些进程,再次运行它时,系统重新创建它,此时会携带一个Intent参数,该参数会保存前次运行的信息。
空进程(empty),不再拥有Activity或其它组件(如:后台接收器BroadcastReceiver)的进程被认为是空进程,系统会很快终结它们。因此,如果你有窗体之外后台操作,请一定在诸如BroadcastReceiver等服务中运行,以便让系统知道该进程不能被终结。
有些时候你需要后台执行一些长时间运行的操作,比如上传视频,此时你应当注册一个后台服务来达到这个目的,并允许用户离开该进程的窗口。这样系统就能正确评价该进程的优先级,把它和那些不可见进程区分开来,不至于轻易终结它。
<-- 完 -->
最后
以上就是满意寒风为你收集整理的Android Activity概述的全部内容,希望文章能够帮你解决Android Activity概述所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复