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是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的状态图,方框代表可以重载的方法,有色的椭圆代表主要状态。 这里有三个关键的回路
        全部寿命(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 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;
     }      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));
             }
         }
     }
 } 保存数据(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;      private SharedPreferences mPrefs;
     private int mCurViewMode;      protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);          SharedPreferences mPrefs = getSharedPreferences();
         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();
     }
 } 权限
详见“安全与权限” 进程生命周期
        Android系统尽可能的保证运行着的进程不被终结,仅当内存不足的时候才开始终结部分进程,来释放资源。进程的终结和它的Activity状态有关。一般来说有四类进程,系统首先终结重要性低的进程,下面按重要性从高到低的顺序来叙述:
        前台进程(foreground),拥有前台窗口的进程是重要性最高的,如果它所需的内存超出设备能力也会被终结。此时为了响应用户界面,系统会达到内存分页状态。
        可见进程(visible),拥有可见窗口的进程拥有次高重要性。
        后台进程(background),不再可见的进程变得不再重要,系统容易终结这些进程,再次运行它时,系统重新创建它,此时会携带一个Intent参数,该参数会保存前次运行的信息。
        空进程(empty),不再拥有Activity或其它组件(如:后台接收器BroadcastReceiver)的进程被认为是空进程,系统会很快终结它们。因此,如果你有窗体之外后台操作,请一定在诸如BroadcastReceiver等服务中运行,以便让系统知道该进程不能被终结。
        有些时候你需要后台执行一些长时间运行的操作,比如上传视频,此时你应当注册一个后台服务来达到这个目的,并允许用户离开该进程的窗口。这样系统就能正确评价该进程的优先级,把它和那些不可见进程区分开来,不至于轻易终结它。 <-- 完 -->

更多相关文章

  1. Android(安卓)Binder
  2. Android进程与线程基本知识
  3. Android深入浅出系列课程---Lesson3 AAF110427_进程生命周期Proc
  4. Android(安卓)入门篇
  5. Android进程so注入Hook java方法
  6. Android(安卓)面试题9
  7. android6.0源码分析之AndroidRuntime的建立过程
  8. Android启动过程——init,Zygote,SystemServer
  9. Android之应用进程模型

随机推荐

  1. Android中的dispatchTouchEvent()、onInt
  2. android api 中文 (75)—— AdapterView.On
  3. Android四大基本组件介绍与生命周期
  4. android Dialog去掉标题栏 和边框
  5. Android中的各种Dialog
  6. android - edittext 默认隐藏软键盘
  7. Android(安卓)利用Sharp样式设置文本框Ed
  8. 使用saripaar对android输入控件进行快速
  9. Android(安卓)uevent
  10. Android用xml写动画效果