Android开发之Activity详解

Activity

  一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号、拍照、发送email、看地图。每一个activity被给予一个窗口,在上面可以绘制用户接口。窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上。

  一个应用程序通常由多个activities组成,他们通常是松耦合关系。通常,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity。每一个activity然后可以启动另一个activity为了完成不同的动作。每一次一个activity启动,前一个activity就停止了,但是系统保留activity在一个栈上(“back stack”)。当一个新activity启动,它被推送到栈顶,取得用户焦点。Back Stack符合简单“后进先出”原则,所以,当用户完成当前activity然后点击back按钮,它被弹出栈(并且被摧毁),然后之前的activity恢复。

  当一个activity因新的activity启动而停止,它被通知这种状态转变通过activity的生命周期回调函数。有许多回调函数一个activity可能会收到,源于它自己的状态变化-无论系统创建它、停止它、恢复它、摧毁它-并且每个回调提供你完成适合这个状态的指定工作的机会。例如,当停止的时候,你的activity应该释放任何大的对象,例如网络数据库连接。当activity恢复,你可以重新获得必要的资源和恢复被中断的动作。这些状态转换都是activity的生命周期的部分。

Creating an Activity

  创建一个activity,你必须创建一个Activity的子类(或者一个Activity的子类的子类)。在你的子类中,你需要实现系统回调的回调方法,当activity在它的生命周期的多种状态中转换的时候,例如当activity被创建、停止、恢复或摧毁。两个最重要的回调方法是:
onCreate()
    你必须实现这个方法。系统调用它当创建你的activity的时候。在你的实现中,你应该初始化你的activity的基本的组件。更重要的是,这里就是你必须调用setContentView()来定义activity用户接口而已的地方。
onPause()
    系统调用这个方法当用户离开你的activity(虽然不总是意味着activity被摧毁)。这通常是你应该提交任何变化,那此将会超越user session而存在的(因为用户可能不再回来)。

  有若干其它生命周期回调函数你应该使用为了提供一个流畅的用户体验,并表操作异常中断会引起你的activity被中断甚至被摧毁。

1、Implementing a user interface

  一个activity的用户接口被一个层次化的视图提供--继承于View类的对象。每个View控制activity窗口中的一个特定矩形区域并且能响应用户交互。例如,一个view可能是个button,初始化动作当用户触摸它的时候。

  Android提供大量预定义的view,你可以使用来设计和组件你的布局。“Widgets”是一种给屏幕提供可视化(并且交互)元素的view,例如按钮、文件域、复选框或者仅仅是图像。“Layouts”是继承于ViewGroup的View,提供特殊的布局模型为它的子view,例如线程布局、格子布局或相关性布局。你可以子类化View和ViewGroup类(或者存在的子类)来创建自己的widget和而已并且应用它们到你的activity布局中。

  最普通的方法是定义一个布局使用view加上XML布局文件保存在你的程序资源里。这样,你可以单独维护你的用户接口设计,而与定义activity行为的代码无关。你可以设置布局作为UI使用setContentView(),传递资源布局的资源ID。可是,你也可以创建新Views在你的activity代码,并且创建一个view层次通过插入新Views到ViewGroup,然后使用那个布局通过传递到根ViewGroup给setContentView()。

Declaring the activity in the manifest

  你必须声明你的activity在manifest文件为了它可以被系统访问。要声明你的activity,打开你的manifest文件,添加一个<activity>元素作为<application>元素的子元素。例如:

Using intent filters

  一个<activity>元素也能指定多种intent filters--使用<inetent-filter>元素--为了声明其它应用程序可以激活它。

  当你创建一个新应用程序使用Android SDK工具,存根activity自动为你创建,包含一个intent filter,声明了activity响应"main"动作,并且应该被 放置 在"launcher"分类。Intent filter看起来像这个样子。

  <action>元素指定这是一个"main"入口点对这个应用程序。<category>元素指定,这个activity应该被列入系统应用程序列表中(为了允许用户启动这个activity)。

  如果你希望应用程序自包含,并且不希望别的应用程序激活它的activities,那么你不需要任何其它intent filters。只有一个activity应该有“main"动作和”launcher“分类,就像前面这个例子。你不希望被其它应用程序访问原Activities应该没有intent filters而且你能启动他们通过自己显示的intent。

  可是,如果你希望你的activity响应影含的intents,从其它应用程序(和你自己的),那么你必须定义额外的intent filters为这个activity。每一种你希望响应的类型的intent,你必须包含<intent-filter>,包含<action>元素,可选的,一个<category>元素并且/或一个<data>元素。这些元素指定你的activity能响应的intent的类型。

Starting an Activity

  你可以开启另一个activity通过startActivity(),传递一个Intent描述了你希望启动的Activity。Intent指定要么准备的activity你希望启动或描述你希望完成的动作(操作系统选择合适的activity为你,可能来自定不同的应用程序)。一个intent可以传输小量数据被启动的activity使用。

  完全工作在你的应用程序之内,你将经常需要简单的启动一个未知的activity。你可以这么通过创建一个intent显示的定义你希望启动的activity,使用类名。例如,下面显示一个activity怎么启动另一个activity命名为SignInActivity:

  可是,你的应用程序或许希望执行一些动作,例如发送一份邮件、文件消息或者状态更新,使用你的activity的数据。在这种情况下,你的应用程序或许没有它自己的activity来完成这个动作,因此你可以促使设备上其它应用程序提供的activity来完成你的动作。这才是intent真正有价值的地方--你可以创建一个intent描述一个你希望执行的动作,然后系统启动一个合适的activity从其它应用程序。如果有多种activities可以处理这个intent,那么 用户可以选择哪一个来执行。例如,如果你希望允许用户发送邮件,你可以创建下面的Intent: 

  EXTRA_EMAIL额外的添加给intent一个字符串数组指定email地址,当一个邮件应用程序响应这个intent的时候,它读取这些字符串数组并且放置他们到相应字段。在这种情况下,email应用程序的activity启动并且当用户执行完,你的activity恢复。

Starting an activity for a result

  有时,你或许希望接收一个结果从你启动的activity。在这种情况下,开启这个activity通过startActivityForResult()(而不是startActivity())。然后从随后的activity接收结果,实现onActiviryResult()回调函数。当随后的activity完成,它返回一个结果给你的onActivityResult()函数通过一个intent。

  例如,或许你希望用户选择他们中的一个联系人,所以你的activity可以对这个联系人做些事情。下面是你怎么建立这样一个Intent和操作结果:

  这个例子展现了基本的逻辑你应该使用的在你的onActivityResult()函数中,为了操作一个activity的结果。第一个条件检测是否请求成功--如果是,那么 resultCode将会是RESULT_OK--并且是否这个请求是否是这个响应是响知道--在这种情况下,requestCode匹配第二个参数用startActivityForResult()的参数。在那里,代码操作activity结果通过查询返回在intent中的数据(data参数)。

  将发生的是,一个ContentResolver实现查询content provider,返回一个Cursor允许读查询的数据。

Shut Down an Activity

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

  注意:在大多数情况下,你不应该显示结果一个activity使用这些方法。正在下文所讨论的关于activity的生命周期,Android系统管理一个activity的生命周期为你,所以你不需要结果你自己的activity。调用这些函数对用户体验有害并且只有在你决对不希望用户返回到这个activity的情况下。

Managing the Activity Lifecycle

  管理你的activity的生命周期通过实现回调函数非常关键对开发一个健壮和有弹性的应用程序。一个activity的生命周期直接被与其相关联的其它activity影响,task和bask stack。

  一个activity可以存在于主要的三种状态:

  1、Resumed

    activity在前景并且拥有用户焦点。(这个状态有时也叫”running“)

  2、Paused

    另一个activity在前景并且拥有用户焦点,但这个仍然可见。也就是说,另一个activity可见在这个的上面,当前activity部分透明或没有覆盖整个屏幕。一个paused activity完全活着(the Activity对象维在内存中,它维护所有的状态并且记忆信息,仍然连接着窗口管理器),但是可以被系统杀死在极端需要内存的情形下。

  3、Stopped

    一个activity被另一个activity完全阻挡(activity现在在后台)。一个stopped activity仍然活着(Activity object维持在内存中,它维扩所有的状态和成员信息,但没有绑定窗口管理器)。可是,它不再被用户可见并且它可被系统销毁在需要的地方。
  如果一个activity paused或者stopped,系统可以从内存中抛弃它通过要求它结束(调用它的finish()方法),或者简单的杀掉它的进程。当activity再次被打开(在被finished或杀死后),它重新建立所有的东西。

Implementing the lifecycle callbacks

  当一个activity转换到或转换出上面提到的状态,它被通过各种不同的回调函数通知。所有这些回调函数都是hook,你可以覆盖来做合适的工作当你的activity状态变化。下面的activity骨架包含每一个基本的生命周期函数:

  注意:你的这些生命周期函数的实现必须调用父类的实现在你做自己的工作之前,就像上面显示的一样。

  放在一起,这些函数定义了整个生命周期关于一个activity。通过实现这些方法,你可以监视三种嵌套的循环在activity生命周期中。
  1、一个activity的整个生命时间发生在onCreate()和onDestroy()函数。你的activity应该设置全局状态(例如定义布局)在onCreate(),并且释放所有的资源在onDestroy()。例如,如果你的activity有一个线程在后台跑下载数据从网络,它可能创建那个线程在onCreate()然后停止线程在onDestroy()。
  2、一个可视的生命期发生在onStart()和onStop()之间。在这期间,用户可以看见activity在屏幕上并且和它交互。例如,onStop()被调时当一个新的activity开始并且这个不再被可见。在这两个函数间,你可以维持资源那些需要用来展现activity给用户的。例如,你可以注册一个BroadcastReceiver在onStart(),然后注销在onStop()当用户不再看见你显示的东西。系统可能会调onStart(0和onStop()多次在这整个生命线期间,当activity在是否可见间转换的时候。
  3、一个activity的前景生命期发生在onResume()和onPause()之间。在这期间,此activity在所有其它activity之上在屏幕上,并且拥有用户焦点。一个activity可以经常转换进和转换出前景--例如,onPause被调用当设备准备休眠蔌当一个对话框产生。因为这种状态可以经常转换,代码在这两个状态应该轻量为了避免减慢转换速度使得用户等待。

  图像1陈述这些循环并且展现一个activity可以发生的状态转换路径。矩形代表你能实现的回调函数。

  Figure 1. The activity lifecycle.

  同样的生命周期回调函数被列在table 1,更加详细的描述了回调函数放置每一个在activity的事个生命周期,包含是否系统能杀死activity在回调函数完成后。
  
  Table 1. A summary of the activity lifecycle's callback methods.

 

  因为onPause()他们三个中的第一个,一量activity被建立,onPause()是最后一个被保证调用的方法--如果系统必须恢复内存在紧急状态,然后onStop()和onDestroy()可能将不被调用。因此,你应该使用onPause()来写数据(例如edit)的存储。可是,你应该精心挑选哪个信息一定要在onPause()中留住,因为任何何阻塞的操作在这个函数阻塞到下一个activity的转换因而降低用户体验。

Saving activity state
  
  本文简单的提到了什么一个activity被paused和stopped,activity的状态维持着。这是真的因为activity对象仍然在内存当它被paused或stopped--所有的信息关于它的成员变量和当前状态都存在。如此,任何用户的变化在activity中都维持在内存里,所以当activity返回到前景的时候(resumes),这些变化仍然存在。
  可是,当系统摧毁一个activity为了恢复内存,activity对象被摧毁了,所以系统不能简单的以完整状态resume它。代替的是,系统必须创建Activity对象如果用户浏览回它。也就是,用户不知道系统摧毁了activity并且再创建了它,如此,可以希望activity是它刚才的那个。在这种情况下,你可以确定重要的信息关于activity的状态被保留通过实现一个额外的回调函数,允许你保存信息关于你的activity,然后恢复它当系统重新创建它的时候。
  这个你可以保存当前状态信息的回调函数是onSaveInstanceState()。系统调这个函数在摧毁activity这前,并且传递一个Bundle对象。Bundle就是你可存在状态信息的地方,采用name-value对,使用方法如putString()。然后,如果系统杀死你的activity进程并且用户浏览回到你的activity,系统传递Bundle给onCreate,这样你就可以恢复activity状态你在onSaveInnstanceState()时候保存的状态。如果没有信息被保存,传递给onCreate()的Bundle是null。
  注意:不保证onSaveInstanceState()将会被调用在你的activity被摧毁前,因为有不需要存储的情况存在(例如当用户离开你的activity,用户显示的结束)。如果这个方法被调用,它总是在onStop()前,概率性在onPause()前。

  可是,即使你不做什么事也不实现 onSaveInstanceState(),一些activity的状态被activity类的默认onSaveInstanceState实现恢复。特别的,默认的View的onSaveInstance()在布局方面,允许每一个视图提供它自己的信息来被保存。几乎所有 的Android框架中的widget实现这个方法合适的,这样任何可见的变化对UI都自己保存并且恢复当你的activity被创建的时候。例如,EditText widget保存任何文本被用户输入的,并且CheckBox widget保存是否选中还是没选中。惟一的工作要求你的是提供一个惟一的ID(通过android:id属性)给每一个希望保存状态的widget。如果一个widget没有ID,那么 它不保存它的状态。
  虽然onSaveInstanceState()的默认实现保存非常有用的信息关于你的activity UI你仍然会需要覆盖它来保存额外的信息。例如,你或许需要保存成员变量在activity生命期间变化的(和保存在UI中的数据有关,但保存这些UI值的变量却不会被默认保存)。
  因为默认的onSaveInstanceState()帮你 你保存UI状态,如果你覆盖这些方法为了保存额外的信息,你应该每次调用父类的实现关于onSaveinstanState()在做工作之前。
  注意:因为onSaveInstanceState()不保证被调用,你应该用它仅用它记录临时状态关于你的activity--你应该永远不用它来存储永久性数据。代替的是,你应该用onPause()来存储永远性数据(例如保存在数据库中的数据)当用户离开activity。
  
  一个好的方法测试你程序保存状态的功能是简单的转换设备以使屏幕方向改变。当屏幕方向变化,系统摧毁和重建activity为了应用可选的资源,适合新方向的。出于这个原因,你的activity恢复它的状态当创建的时候非常重要,因为用户通常转换屏幕在使用应用程序的时候。

Handling configuratinon changes

  一些设备配置能在运行时改变(例如屏幕方向,键盘是否可用和语言)。当这样的变化发生时,Android重新开启运行中的Activity(onDestroy()被调用,然后onCreate()被调用)。重启行为被设计来帮助应用程序适应新的配置通过自动加载你的应用程序通过可选的资源,你提供的。如果你设置你的activity合适的操作这个事件,它将更有弹性对生命周期中无法预料的事件。
  最好的方法操作配置变化,例如屏幕方向变,就是简单的预定义你应用程序的状态使用onSaveInstanceState()和onRestoreInstanceState()(或onCreate()),就像前面讨论的。

Coordinating activities

  当一个activity启动另一个,他们都在体验生命周期转换。第一个activitypauses和stop(虽然,它不会stop如果他仍然可见在前景),另一个activity被创建。万一这些activities共离数据保存到磁盘或哪,那就让第一个activity不退出在另一个启动前就显得非常重要。相当的情况是,后一个进程启动覆盖了前一个停止的时候。

  生周周期回调被良好的定义了,特别的当两个activities都在同一个进程,并且其中一个启动另一个。下面是操作顺序当activity A启动activity B:
  1、Activity A 的onPause()的方法执行。
  2、Activity B 的onCreate()、onStart()和onResume()方法执行,顺序的。(B现在拥有用户焦点)
  3、如果A不再可见,它的onStop()方法执行。
  
  这种生命期函数调用序列允许你从一个activity到另一个的信息转换。例如,如果你必须写入一个数据库,当第一个activity stop,以便让下一个activity能读它,那么你应该写入数据库在onPause()而不是onStop()。

(0)

相关推荐

  • Android使用Messenger实现service与activity交互

    service与activity交互的方式有多种,这里说说使用Messenger来实现两者之间的交互. Service程序: public class MessengerService extends Service { final Messenger mMessenger = new Messenger(new IncomingHandler()); @Override public IBinder onBind(Intent intent) { return mMessenger.getBi

  • Android利用Intent启动和关闭Activity

    一.简介 Android应用程序中一般都有多个Activity,在Activity中,通过调用StartActivity方法,并在该方法的参数中传递Intent对象,就可以实现不同Activity之间的切换和数据传递. 通过StartActivity方法传递intent对象来启动另一个Activity时,可分为两类: l 显式启动:在创建的Intent对象中明确指定启动的是哪个Activity: l 隐式启动:安卓系统根据Intent的动作和数据决定应该启动哪个Activity. 1.显式启动A

  • Android学习小结之Activity保存和恢复状态

    Android中启动一个Activity如果点击Home键该Activity是不会被销毁的,但是当进行某些操作时某些数据就会丢失,如下: Java class: package com.king.activitytest2; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import

  • Android 启动activity的4种方式及打开其他应用的activity的坑

    Android启动的四种方式分别为standard,singleTop,singleTask,singleInstence. standard是最常见的activity启动方式,也是默认的启动的方式.当启动一个activity的时候他将进入返回栈的栈顶.系统不会管栈内是否有相同的activity,方式像后入先出. singleTop方式是在活动启动的时候,系统先判定栈顶是否有相同的活动,如果没有则新建活动,否则将不新建活动.而是直接使用他. singleTask方式在活动启动的时候,系统先判定栈

  • Android开发中Activity的生命周期及加载模式详解

    本文给大家介绍Activity的生命周期,如果大家学习过iOS的小伙伴的话,Activity的生命周期和iOS中ViewController的生命周期非常类似.生命周期,并不难理解.一个人的生命周期莫过于生老病死,花儿的生命周期就是花开花谢了.在Android中Activity的生命周期莫过于Activity的创建到消亡的过程了.本篇博客就会介绍Activity生命周期中的不同阶段,通过实例的形式来窥探一下Activity的生命周期.搞明白Activity的生命周期是至关重要的,因为只有搞明白每

  • Android Activity与Intent详解及示例代码

    Android有三个基础组件Activity,Service和BroadcastReceiver,他们都是依赖Intent来启动.本文介绍的是Activity的生命周期以及针对Activity的Intent使用. 之前的例子一直都是使用Activity,在一个Layout XML与一个Activity捆绑的情况下可以视为一个Form,多个Layout XML与一个Activity捆绑的话那就是个Application本身了.Intent可以分为显式Intent和隐式Intent:显式Intent

  • Android开发中Activity创建跳转及传值的方法

    在Android系统的江湖中有四大组件:活动(Activity), 服务(Service), 广播接收器(Broadcast Reciver)和内容提供者(Content Provider). 今天所介绍的就是Android开发中的四大组件之一:Activity,其他那三大组件以后再进行介绍.说道Android中的Activity,如果你做过iOS开发的话,Activity类似于iOS中的ViewController(视图控制器).在应用中能看到的东西都是放在活动中的.活动是安卓开发比较重要的东

  • Android开发之activity的生命周期详解

    本文实例讲述了Android activity的生命周期.分享给大家供大家参考,具体如下: activity类处于android.app包中,继承体系如下: 1.Java.lang.Object 2.android.content.Context 3.android.app.ApplicationContext 4.android.app.Activity activity是单独的,用于处理用户操作.几乎所有的activity都要和用户打交道,所以activity类创建了一个窗口,开发人员可以通

  • Android开发之Activity详解

    [Activity] 一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号.拍照.发送email.看地图.每一个activity被给予一个窗口,在上面可以绘制用户接口.窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上. 一个应用程序通常由多个activities组成,他们通常是松耦合关系.通常,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity.每一个activ

  • Android开发之AppWidget详解

    Android通知系统是它的一大特色,而其中,AppWidget是其中一个亮点.在开发应用的中,很多时候可以为其添加一个AppWidget显示在桌面中,及时方便的与用户进行 交互.这里就简单的熟悉一下开发一个AppWidget的流程吧. 想要在应用中创建一个AppWidget,至少需要以下几样东西: 需要创建一个AppWidgetProviderInfo,来描述AppWidget的元数据. 需要实现一个自己的AppWidgetProvider对AppWidget进行更新等操作. 需要布局文件来描

  • Android开发之Activity管理工具类完整示例

    本文实例讲述了Android开发之Activity管理工具类.分享给大家供大家参考,具体如下: 这个工具类是对Activity的一些管理,非常适用 package com.maobang.imsdk.util; import java.util.Stack; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.graphics

  • Android开发之Activity全透明渐变切换方法

    Activity全透明渐变切换 类似于Dialog的显示动画效果一样 1. 先设置Acitivity为去透明,在取消掉Activity默认的切换动画 <style name="AppTheme2" parent="Theme.AppCompat.Light"> <!-- Customize your theme here. --> <item name="windowNoTitle">true</item

  • Java微服务开发之Swagger详解

    目录 一.Swagger的作用和概念 1.Swagger 的优势 2.SwaggerUI 特点 2.SpringBoot集成Swagger 3.配置Swagger 4.实体配置 5.其他皮肤 一.Swagger的作用和概念 ​ 官方地址:https://swagger.io/ ​ Swagger 是一个规范且完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务以及 集成Swagger自动生成API文档. ​ Swagger 的目标是对 REST API 定义一个标准且和

  • IOS 开发之UISearchBar 详解及实例

    IOS UISearchBar 详解 iPhone开发之UISearchBar学习是本文要学习的内容,主要介绍了UISearchBar的使用,不多说,我们先来看详细内容.关于UISearchBar的一些问题. 1.修改UISearchBar的背景颜色 UISearchBar是由两个subView组成的,一个是UISearchBarBackGround,另一个是UITextField. 要IB中没有直接操作背景的属性.方法是直接将 UISearchBarBackGround移去 seachBar=

  • iOS开发之UITableView详解

    一.UITableView基本介绍 默认的UITableView有2种风格: UITableViewStylePlain(不分组) UITableViewStyleGrouped(分组) UITableView中的数据只有行的概念,没有列的概念,UITableView的每行数据就是一个UITableViewCell. 自带的UITableViewCell的类型选择有: 复制代码 代码如下: typedef NS_ENUM(NSInteger, UITableViewCellStyle) {   

  • iOS开发之UIScrollView详解

    介绍:UIScrollView用于在一个小范围里显示很大的内容的控件.通过用户平滑.手捏手势,在这个小区域里查看不同内容.是UITableView和UITextView的父类.它是视图,但是比较特殊,可以看成把它看成2层的结构.上面是它的frame层,跟一般试图一样,是它的可见区域,下面层是contentView,可以滑动. 父类UIView方法 复制代码 代码如下: // autoresizingMask - 现在基本弃用,改用autoLayout typedef NS_OPTIONS(NSU

  • Android开发之EditText框输入清理工具类示例

    本文实例讲述了Android开发之EditText框输入清理工具类.分享给大家供大家参考,具体如下: 这个工具类主要用于清理输入框的.当然有的还要依情况而定 package com.maobang.imsdk.util; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.widget.EditText; import android.wid

随机推荐