Android开发指导文档(译)--Activity

各位看客要多给意见,有什么理解错的地方一定要指出来,please!

 


 

Activities

       Activity是一个提供了显示的构件,用户可以用它交互。如打电话,照相,发邮件或浏览一个地图。每一个有一个窗口用来绘制用户接口。该窗口一般充满整个屏幕,但是也可能比屏幕小,浮在其他窗口的上面。

       一个应用程序通常由多个activity组成,它们彼此松散的绑定在一起。通常,应用程序会指定一个activity作为”mainactivity。这个activity往往在加载程序的第一时间呈献给用户。每个activity可以启动其它的activity来执行不同的动作。同一时间一个activity启动,先前的activity就会停止(stop),但是系统会将其保存在一个栈中(back stack)。当新的activity启动,它将被压入栈中并放弃用户焦点。这个back stack遵守后进先出的机制,因此,当用户完成了对当前activity的操作,按下BACK键时,当前的acivity就会弹出栈(然后destroyed),先前的activity恢复(resume)。(更多内容见文档)

       当一个activity因一个新的activity启动而停止时,通过activity生命周期回调函数来通知状态的改变。这个activity或许会有多个回调函数接到通知,因为状态的改变—--无论是系统在(create),停止(stop),恢复(resume),或销毁(destroy)-----每个回调函数提供给你了在activity状态改变时适合执行何种工作的机会。当activity恢复的时候,你可以请求必要的资料和恢复被打断的动作。

 


如何创建一个Activity

创建一个Activity    

必须继承自Activity类,并且实现它的回调函数,这些回调函数是当activity在各个生命周期状态转换时由系统调用,比如activity被创建(create),停止(stop),恢复(resume),或销毁(destroy)

两个最为重要的回调函数是:

onCreate()

       你必须实现这个方法,系统在创建activity时调用。在你的实现中,你应该初始化你的activity的重要构件,最为重要的是,在这里你必须调用setContentView()来设置你的activity的用户接口的布局(layout

onPause()

       系统调用该方法的第一迹象是,用户正在离开你的activity(虽然他不总是意味着被销毁)。在这里你应该保证所有需要存储的改变已记录(因为用户可能不再回来...).

 

实现一个用户接口:

activity的用户接口有一个views的层次化的体系提供----继承自View类的对象。每个view控制一个在activity窗口中的特定的矩形空间并且可以与用户的交互做出反应。比如,一个view可以是一个按钮,该按钮在被用户触摸时执行一个动作。

Android已经提供了许多已经构建好的view。你可以用它们来设计和组织你的布局。”Widgets”是可以在屏幕上可视(和可交互)的view,如按钮(button)、输入框(text field)、checkbox或者只是一幅图片。”Layout”是继承自ViewGroupview,它们为子view提供了独特的布局模型,如linear layout(线性布局),grid layout(表格布局)或relative layout(相对布局)。你可以继承ViewViewGroup类来定义自己的 widget,并将其使用到你的activity布局中。

views定义布局的最普通的方法是使用资源文件中的XML布局文件。这样,你可以保持界面设计与定义你的activity行为的源代码分离的设计理念。你可以传递布局文件的IDsetContentView()来设置该布局为你的activityUI。当然,你也可以创建一个新的View,并将新的View插入到ViewGroup来构建一个新的体系结构,然后将根ViewGroup传递给setContentView()

 

manifest文件中声明activity:

你必须在manifest文件中声明你的activity来使系统接受它。

 

 

<activity>标签有很多属性,你可以将它们包含到元素中,来声明各种属性,如activity的标签(label)或图标(icon)或者UI的主题(theme)。

       一个<activity>元素可以指定各种过滤器----<intent-filter>元素---来声明其他的应用程序构件如何激活它。如下:

 

 

<action>元素指出这是应用程序的”main”入口。<category>元素指出这个activity应该被放到系统应用程序luncher(使用户可以启动这个activity)。

       如果你打算让你的应用程序自用(self-contained),不允许其他的应用程序激活它的activity,你就不需要任何其它的过滤器。只有一个activity应该有”mainaction和”launcher”类。如前边的例子,你不希望让其他应用程序使用的activity应该没有intent过滤器,你可以用explicit intent来启动它们。(下一节描述)

       如果你希望你的activity对别的应用程序(或你自己)发来的implicit intent作出回应的话,你必须为你的activity声明额外的intent过滤器。<intent-filter>必须包含<action>,可选择性的包含<category><data>


启动一个Activity

你可以用startActivity()来启动另一个activity,需要传递给方法一个Intent对象来描述你要启动的activity。这个intent或者指定你想启动的确切的activity或者描述你想执行的动作的类型(系统会为你选择合适的activity,该activity可以不在一个程序中)。Intent也可以携带一些activity启动后需要的数据。例如:

   

 

或许你的应用程序想要执行什么动作,如发送email,文本信息或状态更新。在这种情况下,你的应用程序或许没有执行这些动作的activity,你可以利用其他为应用程序的activity来执行这些动作。这就是intent有用之处----你可以创建一个描述了您想要执行的动作的intent,系统会为你从其他应用程序加载一个合适的activity。如果有多个这样的activity,用户可以选择其中一个。比如,如果你想用户发送一个email信息,你可以创建这样的intent:

 

 

被额外的添加给intentEXTRA_EMAIL是一个字符串数组,该数组存放了你想发送的email的地址。如果一个email程序对该intent做出反应,它会使用额外提供的这个字符串数组,并将里面的地址填在“发送到”输入框,这种情况下,email程序的activity启动,在用户完成操作后,你的activity恢复。

 

 

启动一个获得结果的Activity

       有时候你希望从你启动的activity获得结果,在这种情况下通过startActivityForResult()来启动一个activity。为了获得从随后的activity获得结果intent,需要实现onActivityResult()回调函数。当随后的activity完成操作,它就会在一个Intent中将结果返回给onActivityResult()方法。

       举例,或许你想你的用户pick一个通讯录:

 

 

这个例子显示了你如何在onActivityResult()中获得activity结果的基本的逻辑。第一个条件检查请求是否成功----如果成功,那么resultCode是RESULT_OK---并检查相应的结果的请求是否可知---在这种情况下,resultCode匹配startActivityForResult()的第二个参数。在这里可以通过方法返回的数据获得activity的结果。

       接下来,一个ContentResolver执行对一个content provider的查询。返回一个允许读取查询数据的游标(Cursor)。

 


关闭一个Activity:

你可以通过调用finish()方法关闭一个activity。你也可以通过调用finishActivity()方法关闭一个之前启动的独立的activity

Note:在大多数情况下,你不应显式的用方法结束一个activityAndroid系统管理着activity的生命周期,你不需要finish你的activity

 


Activity生命周期:

通过实现回调函数管理你的activity的生命周期对开发一个健壮和扩展良好的程序来说是非常重要的。一个activity和其他的activity以及它的taskback stack共同影响着activity的生命周期。

       一个activity可以以以下三个基本的状态存在:

Resumed

这个activity在屏幕的最前面,并获得了用户的焦点。

Paused

       另一个activity在前景并拥有焦点,但是现在的这个activity仍可见。换句话说,在一个activity外层有另一个activity,外层的activity不完全透明或者并没有覆盖住全部的屏幕。一个paused activity 是完全存活的(Activity对象仍驻留在内存中,保存了所有的状态和成员信息,并保留了与窗口管理器的连接),但是在系统缺少内错的情况下可被kill

Stopped

       这个activity彻底被另一个activity掩盖(这个activity在后台了)。一个stopped activity也是存活的。然而用户已经看不到它,并且在系统缺少内存的情况下可被kill

 

如果一个activitypausestop,系统可以通过调用finish()函数或者kill它的进程来将其从内存中清除。当这个activity再次被打开时(被finishkill后),必须重新create

 

实现生命周期回调函数:

       activity在上述不同的状态间转换的时候,是通过各种回调函数来得到通知。所有的回调函数都是hook,你可以重写它们来在你的activity状态变化时完成合适的工作。如下的activity包含了各个基本的生命周期函数:

 

 

 

注意:在生命周期函数开始必须先调用父类方法,然后再做自己的工作。

Activity的生命周期包含三个循环:

 

  •  entire lifetime

entire lifetimeonCreate()onDestroy()之间。你的activity应该在onCreate()中执行全局状态的设置(如定义layout,onDestroy()中释放剩余的资源。比如你的activity有一个线程正在后台从网络上下载数据,你因该在onCreate()中创建这个线程并在onDestroy()中释放它。

  •  visible lifetime

一个activityvisible lifetimeonStart()onStop()之间。在此期间,用户可以在屏幕上看到这个activity,并可以与之交互。比如,当一个新的activity被启动时,当前的activity不再可见,这时候会调用该activityonStop()方法。在这两个方法之间你可以持有需要将activity显示给用户的资源。比如说,你可以在onStart()中注册一个BroadcastReceiver来监视影响你的UI的变化,并在用户看不到显示的内容时在onStop()中注销它。在entire lfetime中因为activity可能在可视和隐藏之间多次转变,所以onStart()onStop()或许会多次调用。

  • foregroundlifetime

一个activityforeground lifetimeonResume()onPause()之间。在此期间activity在所有其它activity的前面,并获得了用户焦点。一个activity可能会在前台(foregroud)和后台间转换。比如说,当设备休眠或者一个对话框出现时onPause()被调用。因为这个状态转变的过于频繁,因此在这两个方法中的代码应该是轻量级的,这样避免了用户的等待。

 

下图显示了activity的生命周期:

 

下面列出了各方法更多的细节:

方法名

描述

可被kill?

Next

onCreate()

activity 第一次创建时调用.在这里你应该做所有正常的静态设置创建view或把数据绑定到list等。这个方法传递一个包含activity先前状态(如果这个状态是被捕捉的)的Bundle对象。

No

onStart()

    

onRestart()

activity stop时调用

No

onStart()

onStart()

Activity对用户可见时调用。

No

onResume() 
or
onStop()

    

onResume()

开始于用户交互时(获得用户焦点)调用. 在此时activity activity stack的顶端

No

onPause()

onPause()

在系统要resume另一个activity时调用. 该方法常被用于处理一些改变了的持久化数据的保存,停止动画或者其他消耗CPU的动作。它应该执行的尽可能快,因为下一个activity只有在该方法返回时才能被resume

Yes

onResume() 
or
onStop()

onStop()

Activity对用户不在可见时调用.

Yes

onRestart()
or
onDestroy()

onDestroy()

Activity被销毁时调用.

Yes

nothing

 

 

 

保存activity 的状态:

在前面的介绍中简单的提到了当一个activitypausestop时,activity的状态已被保存。这是因为在此时Activity对象仍然在内存中---它所有的关于成员的信息和当前的状态仍然是存活的。因此,为了在activity返回到前台时(当它resume时)用户对这个activity的所有改变还存在,需要将这些改变保持在内存中。

       然而,当系统为了回收内存而销毁了这个activity时,这个Activity对象被销毁了,系统不能再简单的将其完好无损的resume。如果用户希望用导航键back回到该activity,系统只能在重新创建Activity对象。此时用户并不知道系统销毁了这个activity后有重新创建了一个,因此或许会认为这个就是以前那一个。在这种情况下,你通过实现一个附加的回调函数来保存你的activty的状态的信息,然后在系统重新创建它时时恢复这些信息。通过这种方式你可以确信你的activity的重要信息被保护。

       可以保存你的activity的当前状态的回调函数是onSaveInstanceState()。这个回调函数在activity容易被销毁的时候调用,并会传递一个Bundle对象给它。你可以将activity的状态信息以键值对的形式,用putString()等方法存放到Bundle中。如果系统kill了你的activity的进程,而用户用back键想回到该activity,系统会将这个Bundle传递给onCreate(),这样你就可以在恢复在onSaveInstanceState()中保存的数据了。如果没有信息要恢复,传递给onCreate()函数的Bundle将会是null

       注:在你的activity被销毁之前,onSaveInstanceState()方法并不能保证一定会运行,因为有这样一种情况就是状态信息根本不需要保存(如用户想用BACK键离开时,他希望的是关闭这个activity)。这个方法往往在onStop()onPause()前调用。

       然而,即使你没有实现onSaveInstanceState(),一些activity的状态在Activity类的默认的onSaveInstanceState()实现中保存。特别的,拿布局中的View的对onSaveInstanceState()来说,它允许每个view为它自己提供需要保存的信息。在Android框架中几乎所有的widget都视情形实现了这个方法。因此所有UI的可见的变化都被自动保存并在activity重新创建时恢复。比如说,EditText widget会保存所有用户输入的文本,CheckBox widget会保存它是否被选中。你唯一需要做的是为每个你想保存其状态的widget设置一个独一无二的ID(使用android:id属性)。如果widget没有ID,它将不能保存它的状态。

       虽然对onSaveInstanceState()的默认实现为你的activityUI保存了有用的信息,但是你仍然需要重写该方法来保存一些额外的信息。比如说,你或许需要保存一些在activity生命期内改变的成员变量。

       当你重写onSaveInstanceState()时,应该将在你所有的工作之前调用父类对该方法的默认实现。

       注:因为onSaveInstanceState()方法并不一定被调用,你应该用它记录暂时的状态---你不应该用它存储persistent数据(比如要保存到数据库的数据)而是使用onPause()方法来存贮。

       一个检测你的应用程序恢复状态的能力的好方法是旋转你的设备,这样屏幕的方向会发生改变。当屏幕方向改变时,系统会销毁并重新创建一个activity来申请备用的能适应新方向的资源。基于这个原因,当activity被重新创建是完全的恢复其状态是非常重要的,用户经常会在使用应用程序时会经常旋转屏幕。

      

处理配置信息的改变:

许多设备的配置在运行时常常改变(如屏幕方向,键盘是否可用,语言等)。当发生这种改变时,Android会重启一个运行的Activity(onDestroy()被调用,随后调用onCreate())。这种restart行为设计是为了使你的应用程序适应新的配置,这些配置是由你所提供的可替换的资源自动的重新加载你的应用程序得到的。如果你设计你的activity来妥善的处理这些事件,在activity的生命周期处理突发事件会很有弹性。

处理配置改变的最好方法是如前面一节讲述的那样用onSaveInstanceState()

onRestoreInstanceState()(onCreate())方法保存你应用程序的状态。

 

协调的activity:

       当一个activity启动另一个时,它们都在经历生命周期的变换。当另一个activity被创建时,第一个activity pausestop(虽然它在后台运行仍然可视时不会stop)。如果这些activity共享的数据被保存到硬盘或者光盘中,重要的是要理解,在第二个activity被创建前,第一个activity并未完全的stop。相反的,启动第二个activity的进程会与stop第一个的进程重叠。

Activity生命周期回调函数的调用顺序非常明确,尤其是两个activity在同一个进程中并且一个activity启动另一个时。下面当Activity A 启动 Activity B 时操作执行的顺序:

1、  Activity AonPause()方法执行。

2、  Activity BonCreate(),onStart()onResume()方法执行。(这时Activity B获得了用户焦点)

3、  如果Activity A在屏幕上不在可见时,它的onStop()方法执行。

这种可预料的生命周期函数调用的次序使你能够管理从一个activity到另一个转换的信息。比如说,如果你在第一个activity stop时向数据库写入信息以便在第二个activity可以读取它,这时你应该在onPause()中写入数据库,而不是在onStop()时写入。

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
首先,ActivityAndroid系统中的四大组件之一,可以用于显示View。Activity是一个与用记交互的系统模块,几乎所有的Activity都是和用户进行交互的,但是如果这样就能说Activity主要是用来显示View就不太正确了。 在深入了解Activity之前,我们先要知道一下MVC设计模式,在JAVAEE 中MVC设计模式已经很经典了,而且分的也比较清晰了,但是在Android中,好多人对MVC在Android开发中的应用不是很清楚,下面我就先来介绍一下MVC在Android开发中的应用: M(Model 模型):Model是应用程序的主体部分,所有的业务逻辑都应该写在这里,在Android中Model层与JavaEE中的变化不大,如:对数据库的操作,对网络等的操作都放在该层(但不是说它们都放在同一个包中,可以分开放,但它们统称为Model层)。 V(View 视图):是应用程序中负责生成用户界面的部分,也是在整个MVC架构中用户唯一可以看到的一层,接收用户输入,显示处理结果;在Android应用中一般采用XML文件里德界面的描述,使用的时候可以非常方便的引入,当然也可以使用JavaScript+Html等方式作为View。 C(Controller控制层)android的控制层的重任就要落在众多的activity的肩上了,所以在这里就要建议大家不要在activity中写太多的代码,尽量能过activity交割Model业务逻辑层处理。 好了,在介绍过Android应用开发中的MVC架构后,我们就可以很明确的知道,在AndroidActivity主要是用来做控制的,它可以选择要显示的View,也可以从View中获取数据然后把数据传给Model层进行处理,最后再来显示出处理结果。 介绍过Activity的主要作用后,那么我们就要详细说一下Activity了。 Activity生命周期图 Activity 的生命周期是被以下的函数控制的。 public class Activity extends ApplicationContext { protected void onCreate(Bundle icicle); protected void onStart(); protected void onRestart(); protected void onResume(); protected void onFreeze(Bundle outIcicle); protected void onPause(); protected void onStop(); protected void onDestroy(); } onCreate(Bundle) 函数是你进行初始化的地方,这个也是执行 setContentView(View)函数的地方,setContentView(View)函数可以传入一个由XML 编制的UI界面,可以使UI和具体实现完全分离。 onPause()函数是处理用户离开当前 Activity 的地方。更重要的是,任何在当前 Activity中的任何改变都要在这个函数中提交。 Activity有四种状态: 活动状态,当Activity处于Stack(栈)顶时,就是手机当前的现实屏幕,这是 Activity就 处于activity或者运行状态。 运行但是失去焦点,当Activity还处于运行状态时,但是屏幕是有另外一个Activity 处于文档处于焦点状态,当前的Activity就处于pause。 停止,当Activity被另一个Activity完全覆盖的时候,就被停止了,其实就是虽然在 运行,但是用户却看不见。 结束,当Activity处于pause或者stop时,系统可以结束 Activity,回收资源,这 是Activity就是处于结束状态了。 处于结束状态的是Activity,如果要使用户可见,只要重启才可以。 Activity的响应时间 当前Activity所在的线程为主线程,它的响应时间为5秒,如果在当前运行的Activity中进行耗时的操作且响应时间起过5秒,那么程序就会报ANR错误。所以,这也是不建议在Activity中写太多复杂代码的原因之一。 当然,有些代码只能写在Activity中,不然就运行不了(它们不是生命周期方法),比如你想要获得android系统或者硬件一的些信息,就必须在Activity中写出来,如果单独写一个工具类获得不了。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值