Android之Activity

Android之Activity 

Activity是Android系统提供的界面,所有和用户的交互都发生在这里(类似于windows的窗口)。Activity在创建时生成各种控件 视图(View),这些视图负责具体功能,例如ListView。Activity通常使用全屏模式,也有浮动窗口模式(通过设置属性 windowIsFloating)和嵌入模式(参见ActivityGroup)。

它的继承类通常要重载两个方法:

1. onCreate(Bundle)是初始化函数,在这里可以调用setContentView(int)方法来设置界面布局(layout),也可以通过findViewById(int)方法来获取其子控件。

2. onPause()是失去焦点后所调用的函数,重要的是应该在这里保存用户的输入,通常用ContentProvider暂存这些数据。

程序包(package)在AndroidManifestxml文件中声明你要首先启动哪个Activity,ContextstartActivity()会根据其中相应的<Activity>设置来启动。

一、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打断用户输入和提交保存数据。

在android中,Activity拥有四种基本状态:

1.Active/Runing一个新Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。

2.Paused 当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。

3.Stoped 当Activity 被另外一个 Activity 覆盖、失去焦点并不可见时处于 Stoped状态。

4.Killed Activity 被系统杀死回收或者没有被启动时处于 Killed状态。

二、进程生命周期

Android系统尽可能的保证运行着的进程不被终结,仅当内存不足的时候才开始终结部分进程,来释放资源。进程的终结和它的Activity状态有关。一般来说有四类进程,系统首先终结重要性低的进程,下面按重要性从高到低的顺序来叙述:

前台进程(foreground),拥有前台窗口的进程是重要性最高的,如果它所需的内存超出设备能力也会被终结。此时为了响应用户界面,系统会达到内存分页状态。

可见进程(visible),拥有可见窗口的进程拥有次高重要性。

后台进程(background),不再可见的进程变得不再重要,系统容易终结这些进程,再次运行它时,系统重新创建它,此时会携带一个Intent参数,该参数会保存前次运行的信息。

空进程(empty),不再拥有Activity或其它组件(如:后台接收器BroadcastReceiver)的进程被认为是空进程,系统会很快终结 它们。因此,如果你有窗体之外后台操作,请一定在诸如BroadcastReceiver等服务中运行,以便让系统知道该进程不能被终结。

有些时候你需要后台执行一些长时间运行的操作,比如上传视频,此时你应当注册一个后台服务来达到这个目的,并允许用户离开该进程的窗口。这样系统就能正确评价该进程的优先级,把它和那些不可见进程区分开来,不至于轻易终结它。

三、Activity 之间通信

1)使用 Intent 通信

 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。

2)使用 SharedPreferences

SharedPreferences使用 xml 格式为 Android 应用提供一种永久的数据存贮方式。对于一个 Android 应用,它存贮在文件系统的 /data/ data/your_app_package_name/shared_prefs/目录下,可以被处在同一个应用中的所有 Activity 访问。Android 提供了相关的 API 来处理这些数据而不需要程序员直接操作这些文件或者考虑数据同步问题。

3)其它方式

Android 提供了包括 SharedPreferences 在内的很多种数据存贮方式,比如 SQLite,文件等,程序员可以通过这些 API 实现 Activity 之间的数据交换。如果必要,我们还可以使用 IPC 方式。

四、一些Activity 的技巧

1)锁定 Activity 运行时的屏幕方向

Android 内置了方向感应器的支持。在 G1 中,Android 会根据 G1 所处的方向自动在竖屏和横屏间切换。但是有时我们的应用程序仅能在横屏 / 竖屏时运行,比如某些游戏,此时我们需要锁定该 Activity 运行时的屏幕方向,<activity >节点的 androidscreenOrientation属性可以完成该项任务

2)全屏的 Activity

要使一个 Activity全屏运行,可以在其 onCreate()方法中添加如下代码实现:

// 设置全屏模式

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCRE EN,

WindowManager.LayoutParams.FLAG_FULLSCREEN); 

// 去除标题栏

requestWindowFeature(Window.FEATURE_NO_TITLE); 

  3)在 Activity 的 Title 中加入进度条

为了更友好的用户体验,在处理一些需要花费较长时间的任务时可以使用一个进度条来提示用户“不要着急,我们正在努力的完成你交给的任务”。 在 Activity 的标题栏中显示进度条不失为一个好办法,下面是实现代码:

// 不明确进度条

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 

setContentView(R.layout.main);

setProgressBarIndeterminateVisibility(true);

// 明确进度条

requestWindowFeature(Window.FEATURE_PROGRESS);

setContentView(R.layout.main);

setProgress(5000);

posted @ 2012-12-11 11:36  JD.Tang  阅读(323)  评论(0编辑  收藏  举报