Activity-原文

来源:互联网 发布:知乎 如果国民党 编辑:程序博客网 时间:2024/05/01 18:50

Activity  原文翻译

 

一、定义:

         活动是一个用户操作的、单独的、获得焦点的东西。

 

二、要点:

1.概述

2.生命周期

3.配置变化

4.启动活动与获取结果

5.保存永久状态

6.权限

7.进程生命周期

 

三、正文:

 

1. 概述

         活动是一个用户操作的、单独的、获得焦点的东西。差不多所有的活动都与用户交互,因此Activity类关注于帮你创建一个窗口,在这个窗口中你通过setContentView(View)来放置UI。当然活动通常以全屏形式展现在大家面前,它们也可以有其它形式的使用方式:作为浮动窗口(通过设置主题为:windowIsFloating)或者嵌入到其它活动中(使用ActivityGroup)。这里的两个方法差不多所有活动子类都要实现:

         onCreate(Bundle):初始化活动。重要的是一般调setContentView(int)来通过layout资源以定义UI,并使用findViewById(int)来获取UI部件widgets(那些你需要用程序来控制)。

         onPause():当用户离开活动时,进行处理。更重要的是,用户做的任何变化,当在此点提交(通常用ContentProvider来保存数据)

 

       若想使用Context.startActivity()来叫起活动,所有的活动类必须在 包的清单文件androidManifest.xml中 在节点<activity>中进行声明;

         活动类是一个应用程序的整个生命周期的重要部分,活动被启动和组合在一起的方式是平台的应用程序模型的基础构成部分。若想要详细地了解应用程序的结构及生命周期,请读Dev Gvide Application Funcamentals.

 

2. 生命周期

         系统通过一个活动栈来管理活动。当一个新活动开始后,它被放在栈顶并处于运行态――前一个活动将一直位于栈中些活动的下面,直到这个新活动退出后,它才会回到前台。

         一个活动的必要四态

         A。一个活动处于屏幕前端(在栈顶),它是 激活的 或者 running;

         B。一个活动已丢失焦点但仍可见(也就是一个新的非全屏或者透明的活动已经位于该活动之上),它处于paused。一个暂停态的活动是完全活着的(它保存所有状态和成员信息,并仍然附着在窗口管理器window manager),但可能被系统杀死,当系统处于内存极低的状态时。

         C。一个活动被另一个活动完全遮住时,它处于Stoped状态。它也保存所有状态和成员信息,然而,这已不再对用户可见,因此它的窗口是隐藏的并且当其它地方需要内存时,它常会被系统杀掉

         D。当一个活动处于 Paused 或 Stoped 状态时,系统将从内存中扔掉这个活动,通过 请求它结束 或 直接杀死它的进程。当它再次显示在用户前面时,它必须被完全再启动并恢复到它之前的状态。

 

如下图表显示了活动所处的重要状态路径。矩形代表活动在状态变迁时可以实现进行操作的回调函数,着色的随圆是活动可以处于的主要状态。

 

这里有三条关键的循环路线需要关注,当监察活动时。

A。整个生命周期:活动始于首次调用onCreate(Bundle),直到一次调用onDestory()。在onCreate( )中,一个活动将进行所有的设置或安装操作以达到最终状态,并在onDestory( )中释放所有持有的资源。例如,如果它有一个线程在后台从网络下载资源,它可能要在onCreate() 中创建这个线程,并在onDestory()中结束这个线程

B。可见生命周期:当活动调用onStart()始,直到一个相应的调用到onStop( )。在此期间,用户可以看到活动处于屏幕中,也许也不在前端并与用户交互。在这两个方法里,你可以维护资源以显示活动给用户。例如,你可以注册一个 广播接收者在onStart() 来监听那些会影响到此活动UI的变化,当用户不再察看此活动显示的内容时,并在onStop()里去取消广播接收。

C。前端生命周期:当活动调用onResume()始,直到一个相应的调用到onPause( )。在此期间,活动处于所有其它活动之前并与用户进行交互。一个活动可以频繁地在这两态之间切换――例如,当设备休眠时、当一个活动结果被传递时、当一个新的意图被传送――因此,在这两个方法里面的代码应当相当的轻量级。。

 

Method

Description

Killable?

Next

onCreate()

当活动第一次创建时被调用。这里应该完成常规静态的设置:创建视图、绑定数据到列表等。    这个方法同样提供一个Bundle,它载有此活动先前的冻结状态(的信息),如果此前有被冻结的话。通常会接着调用onStart()。

N

onStart()

onRestart ()

    当活动已被停止,在其正被再次启动之前调用。通常会接着调用onStart()。

N

onStart()

onStart ()

    当活动对用户正变为可见时被调用。如果活动到了前台,将接着调用onResume() ;或者当活动变为被隐藏onStop()将会被调用。[什么意思?在此中调hidden()???]

N

onResume()or onStop()

onResume()

    当活动将开始与用户交互时被调用。此时,活动处于活动栈的顶部。通常会接着调用onPause()。

N

onPause()

onPause()

    当系统将要继续前一个活动时被调用。这个方法最常用来提交未保存的变化到永久数据,停止动画和其它消耗CPU的事情,等。这个方法的实现必须很快因为下一个活动的继续(resume)只有在这个方法返回后才进行。

Pre-HOMEYCOMB

 

onResume()or
onStop()

onStop()

    当此活动不再对用户可见时被调用,因为另一个活动已经被继续且覆盖在此上面。  这个调用发生于:一个新的活动已经启动,一个已经存在的活动正被带到此活动前面, 或者 这个活动正在被销毁。

Y

onRestart() or

onDestory()

onDestroy()

    这个最终调用可以在活动被销毁之前接收。这个调用发生于:1.因为活动正在结束(某调用了finish()在此活动中);2。因为系统为节省空间而临时结束掉此活动实例。   可以通过调用 isFinishing()方法来区分这两种情景

Y

Nothing

 

         注意上表中的“可被杀死列”——那些被标记的方法,在这些方法返回后,拥有此活动的进程将可能被系统在任意时间杀死,并且不会多执行一行代码。鉴于此,应该在onPause()方法中写入永久数据到存储设备中。  此外,方法onSaveInstanceState(Bundle)将在 此活动处于这种后台状态之前被调用,以允许你保存你活动中的动态实例到给定的Bundle中。

         关于进程生命周期是如何关联到它所拥有的活动的更多信息,请参考 进程生命周期  这节。

         注意,在onPause()中保存数据很重要,而不是onSaveinstanceState(Bundle),因为后者并不是生命周期中的一部分,所以如周文档中描述的一样,它并不会在每种情形下被调用

 

         注意。当应用程序目标平台为HONEYCOMB以后(2011.2  ,android 3.0),上述语义将略有变化。3.0之后,只到onStop()返回后,应用程序才会处于killable状态。这影响了onSaveInstanceState(Bundle)可能被调用的时机(它将被安全的调用于 onPause() 之后,并允许应用程序安全的等待只到onStop() 以保存状态。)

        上述未标为可被杀死的方法,在其被调用直到返回其间,系统将不会杀死此活动的进程。因而,例如当活动处于opPause() 于再开始onResume()调用间,这个活动就处于可被杀死状态。

  

3.配置变化

         如果设置的配置发生了变化,那么用来显示一个用户接口的东西须更新以适应此配置。正因为活动是初级的与交互机制,它包括了用来处理配置变化的特别支持。

         除非另作指定,一个配置变化(例如 屏幕方向改变,语言,输入设备,等)将引起你当前的活动被销毁,经历正常的活动生命周期过程:onPause(), onStop(), 及在适当情况下的onDestory() 。如果活动已处于前端或对用户可见,一旦onDestory()在此实例中被调用,然后一个新的实例将会被创建,伴随着savedinstanceState,前一实例在onSaveInstanceState(Bundle)方法中生成的。

         之所以要做这些是因为任何应用程序资源,包括布局文件,可随任意配置值发生改变。因而,唯一安全的用来处理一个配置变化的方法就是重新获取所有资源,包括布局、可绘制部件、字符串。因为活动必须已经知道如何保存它们的状态并从这些状态中重新创建它们自己,这是一个方便的方式来使一个活动再启动自己于一个新的配置中。

         在某些特殊情况下,你可能想要基于一种或多种类弄的配置变化,来 略过 重启活动,这可以通过在清单文件中设置android:configChanges属性来完成。 对于任意类型的配置变化:你声明了要处理的,你将收到一个给你当前活动的调用onConfigurationChagned(Configuration)方法,而非被重启。如果你不处理任何一种变化,活动将重启,并且onConfigurationChagned(Configuration)方法也不会被调用。

  

4.启动活动并获得结果

         方法startActivity(Intent)用来启动一个新的活动。此活动将被放在活动栈栈顶。所带参数Intent描述了将要被启动的活动。

         有时,想从一个结束的活动中获取结果,例如,你可能会启动一个活动以使得用户从联系人列表中选取一人,当此活动结束后,它返回被选中联系人信息。要做到这些,可以调用 startActivityForResult(Intent, int)通过带第二个参数:标识调用。这个结果将返回到onActivityResult(int, int, Intent)方法中。

        当一个活动退出时,也可以调用setResult(int)来返回数据到它的父亲。它必须提供一个结果码,可以是RESULT_CANCELED, RESULT_OK 或者任意起于RESULT_FIRST_USER的自定义值。此外,可选的,它可以返回它想带有的附加数据的Intent。所有这些信息都出现在父活动的onActivityResult()方法中,伴随着一个整数标识:初始时提供的(传入的)。

         如果被调活动(子活动)因任何原因失败(如crashing),父活动将收到一个结果码:RESULT_CANCELED

 

 

5.保存永久状态

通常活动处理两种持久数据:共享文档类似的数据(典型的是存在 SQLite 数据库中,使用content provider)和内部状态如 user preferences.

对于内容提供者数据, 建议活动使用“就地编辑”的用户模型。也就是,用户制作的每一个可编辑处都很高效,而不带有其它的验证步骤。要支持这种模型,常需要坚守下面两个规则:

A.当创建一个新文档,支持数据库条目或文件应被立即创建。例如,如果用户选择写一个新的邮件,一个新的邮件入口在用户输入数据时创建,以使当用户进入其它活动后,邮件会出现在草稿列表中。

         B.当活动的onPause()方法被调用,数据库应当提交到用户创建的支持数据库或文件中。这样可以确保这些改变将被其它的将要运行的活动看见。

 

         这个模型设计是用来防止用户在多个活动中变换时引起数据丢失,并允许系统在活动被暂停后的任意时间安全地杀死一个活动(由于在别处急需系统资源)。注意,这里暗指用户在活动中按“BACK”并不意味着“取消”——它意味着离开此活动并保存当前内容。取消编辑在活动中必须由其它机制来提供,如显示的“revert”或“undo”选项。  

         要想了解更多的关于contentproviders的信息,请参见 content package。这些是一个关于不同活动间如何请求和传递数据的关键方面。 

         活动类同样提供了用于管理内部永久数据的API。这可以被用来,例如,以记住用户的喜欢的初始显示 或 浏览器中用户缺省的主页。

 

         活动永久状态用方法getPreferences(int)来进行管理,允许你获取、修改关于活动的一列名/值对。要在多个应用程序组件(活动,消息接收者,服务,内容提供者)中共享use Preferences,可以通过指定标识由Context.getSharedPreferences()方法来获取一个preferencesobject.(注意:不能够跨应用程序包来共享设置数据——如果那样的话,你需要一个内容提供者。)???

  


6.权限

启动一个特定活动的能力能通过在清单文件中的<activiyt>标记中声明而增强。通过这样做,其它应用程序将需要声明相应的<uses-permission>元素于它的清单文件中以启动那个活动。

参见 Security andPermissions 文档以获取更多关于权限与安全 的一般概念。

 

 

7.进程生命周期

         Android系统尝试保持应用程序运行尽可能长的时间,但最终需要删除旧进程当内存不够时。正如上述活动的生命周期图所示,哪一个进程将被删除,将取决于用户与之交互的密切程度。一般的,运行于进程中的活动有四种状态,在下面按重要程序列出。系统将杀死最不重要的进程(最后一个)在它将要杀死更重要的进程之前(第一个)。

1.foreground activity:前台活动(在屏幕最顶端,正与用户交互的)被认为是最重要的。它的进程将最后被杀死,如果它使用了超出设备可提供的内存。一般的,在此时,设备已到了内存分页状态???因此,这被请求使得用户界面是可响应的。

2.visible activity:可见活动(活动对用户可见,但不处于最前,如处理前台对话框后面。)也是极其重要的,并且除非是为让前台活动继续运行,否则不会被杀死。

3.background activity:后台活动(活动已被暂停,并且不为用户所见)不再关键,因此系统会杀死它为其为前台或可见进程让出空间。如果它的进程需要被杀死,当用户再次进入(原为: navigates back to向后定位到)这个活动(让这个活动再次可见),它的onCreate(Bundle)方法将被再次调用,凭借onSaveInstanceState(Bundle)中提供的savedInstanceSatate使其重启自己以到达用户上次离开的状态。

4.empty process:空进程一个不拥有活动或者其它应用程序组件(如服务 或 广播接收者 类)。当内存不足时,系统会最快的杀死它们。 因此, 在活动之外进行的任何后台操作都必须在一个活动广播接收者或者是服务的上下文中进行,由此以确信系统知道应保持此进程的运行。

 

有时活动可能需要作一耗时操作,而且此操作将独立于活动的生命周期。一个例子便是相机应用与图片上传,当退出相机时,图片仍然在上传。要做到这些,此活动应该启动一个服务以进行上传。这使得系统能够适当的优先推进你的进程(考虑到这将比其它不可见应用更重要)在上传过程中,而无论初始进程是暂停、停止、还是结束了。

 

[亦有五态说,暂不列。。。]

 

四、总结

本文只是简单地翻译了一遍原文,作为实用来讲,意义并不大,主要为引出后续话题。后续将以本文为根,对其进行扩充。

原创粉丝点击