Activity介绍及生命周期.mp4
本章视频二: 主要讲解核心组件Activity的基础知识,包括Activity的功能、生命周期、回调方法等,并通过案例测试Activity回调方法自动调用的逻辑顺序。视频内容涵盖了本章的3.2.1~3.2.3节。
Activity是Android系统中最基本、最常用的组件。Activity为用户提供一个交互接口,它类似于Web应用系统的网页,把数据信息展示给用户浏览;提供数据操作的入口,负责页面跳转,或者调用后台其他功能组件,如服务(Service)、广播发送等。
一个Android应用程序通常由多个Activity组成,但是其中只能有一个默认Activity,在启动时首先展示出来,它类似于Java项目中只能有一个类含有main()程序入口点方法。
Android应用程序中的多个Activity之间可以相互调用,以完成不同的功能。当新的Activity被启动时,上一个Activity失去焦点,被停止运行,压入Activity回退栈Stack。当新的Activity页面使用完毕,用户通过调用返回操作或者点击手机的后退键,当前Activity被销毁,系统从Activity回退栈栈顶弹出原先的Activity,并激活它。如果用户多次点击回退键,系统依次从回退栈弹出Activity,直到栈空。
Activity类是android.content.Context的间接子类,存在于android.app包中,开发者自定义Activity时,必须直接或者间接地继承于Activity类。Activity类常用的方法或属性如表3-1所示。
表3-1 Activity常用的方法或属性
Activity还有很多常用的方法,如启动服务的startService()、发送广播的sendBroadcast()、获取当前文件的openFileInput()等。这些在本书相应章节中将详细介绍。
Activity的生命周期是它从创建、运行到销毁的整个过程。在Android系统中,Activity被一个叫作Activity栈管理,同一个时刻,只有最顶上的Activity处于运行状态。当一个新的Activity创建并运行时,将其压入栈顶成为运行态,先前的Activity保留在栈中,直到新的Activity退出,它才能被恢复。总结起来,Activity在生命周期中有以下三个主要的状态。
· 运行态:是指Activity运行在最上层,并且获得用户焦点的状态。
· 暂停态:是指当前Activity依然存在,但是失去焦点。最上层已有新的Activity处于运行态,但没有完全遮住它,此时它仍然保留自己的内存和用户信息。
· 停止态:当前Activity完全被运行态的Activity遮盖,此时它仍然保留自己的内存和用户信息,但是级别降低,随时可能被系统回收所占的资源。
在Activity生命周期中,每一次状态的变化,都会触发相应的回调方法,这些方法如表3-1中的前7个。开发者自定义Activity时,可以重写这些方法,填入自己的业务代码,实现特定的功能。图3-2更好地展示了Activity生命周期状态变化,以及它们给用户的直观感觉。
图3-2 Activity的整个生命周期
为了更好地理解Activity生命周期各种状态的变化,以及这些状态变化所触发的回调方法,在此设计以下案例。
设计并实现一个案例,只有如图3-3所示的一个Activity页面(页面UI随意),每个回调方法中都打印一条日志,然后按创建→运行→转到其他应用页面→返回本例页面→退出本例的顺序,操作完成后,查看日志信息,分析状态变化。
图3-3 Activity生命周期测试
(1)新建一个项目,命名为LifeCycleDemo,图3-3中的UI设计添加了图片和文字仅做展示和说明,开发者可采用默认页面,不做任何设计。
(2)在MainActivity.java类中,分别重写了onCreate()、onRestart()、onStart()、onResume()、onPause()、onStop()、onDestroy()方法。在这些方法中,使用Log.i(tag, message)打出日志,详见代码。
(3)在LogCat中,创建日志过滤器,只显示开发者打印的日志。根据操作过程,分析日志,得出Activity生命周期状态变化,触发回调的顺序。
本案例MainActivity类代码如下:
使用真机连接开发环境,进行测试运行,以便能按以下顺序完成操作:启动应用程序→展示本页面→跳到其他页面→返回本例页面→退出本例页面。LogCat中通过ActivityLifeCycle过滤器得到的日志如图3-4所示。
图3-4 Activity的生命周期日志
从日志可以看出,Activity的三种状态变化所触发的回调方法,与图3-2所表述的状态变化完全一致。
Activity运用及案例.mp4
本章视频三: 主要讲解核心组件Activity的应用技术,包括Activity的创建、启动、跳转、参数传递等实现方法,并通过案例演示了这些技术的具体应用。视频内容涵盖了本章3.2.4、3.2.5节。
新建Activity有两种方式:根据向导新建和自建。根据向导新建,以Eclipse为例,如图3-5所示,只需按向导步骤,填入相应的名称、版本、图标即可,系统自动创建Activity类和对应的布局描述文件,并自动在AndroidManifest.xml文件中注册。
图3-5 新建Activity向导
自建Activity的一般步骤如下。
(1)新建一个类,必须直接或间接地继承于android.app.Activity。
(2)在res/layout目录下创建一个布局描述XML文件,并重写Activity的onCreate()方法,实现布局描述文件与Activity关联,代码如下:
(3)在AndroidManifest.xml文件中注册Activity,代码如下:
如果希望以该页面为首页,则需要在<activity>节点下加入Intent过滤器,代码如下:
Activity的启动分为两大类:一类是应用程序之间的Activity启动,一般采用隐式启动,本章3.1.5节中已经做了详细讲解。另一类为应用程序内部的Activity启动,它又分为两种情况。
1)无返回值的Activity启动
通常情况下使用Intent作为参数,通过Context.startActivity()实现启动操作,参考代码如下:
2)有返回值的Activity启动
仍然使用Intent作为参数,然后通过Context.startActivityForResult()实现启动操作,参考代码如下:
当AnotherActivity执行完毕返回的时候,触发执行onActivityResult()方法来获取返回值,因此开发者必须重写CurrentActivity的onActivityResult()方法,做好接收返回值的方案。
Activity的数据传递分两种情况,正好与Activity的启动方式相对应。
第一种情况是,当前Activity到目标Activity的参数传递,一般使用Intent即可。这种情况适用于显示启动和隐式启动Activity两种类型,可以传递简单数据类型、字节数组、字符串等参数,参考代码如下:
在AnotherActivity中接收参数的方法如下:
第二种情况是,从目标Activity到原Activity的数据回传,仍然使用Intent承载数据。将需要回传的数据通过Bundle装入Intent对象后,当目标Activity执行了finish()方法后,触发回传操作,原Activity中可以通过onActivityResult()方法接收数据。
在CurrentActivity中启动AnotherActivity,参考代码如下:
以上代码中的REQUEST_CODE是从CurrentActivity到AnotherActivity的请求码,当在CurrentActivity中接收回传数据时,用于区分数据来源。
在AnotherActivity中,使用Intent装载返回值,调用Activity的setResult()方法加入Intent对象,当执行finish()后回传数据,代码如下:
为了接收回传数据,开发者需要在CurrentActivity中重写onActivityResult()方法,用于接收数据,参考代码如下:
设计如图3-6所示的功能页面,单击图3-6(a)所示页面中的第一个按钮,跳转到图3-6(b)所示页面;在图3-6(a)所示页面中填入书名和价格后单击第二个按钮,跳转到图3-6(c)所示页面,并展示传递的参数;单击图3-6(a)所示页面中的第三个按钮,进入图3-6(d)所示页面,输入内容后单击“返回”按钮,将结果值带回主页面。
图3-6 Activity的跳转与参数传递案例
(1)新建一个项目,命名为activityDemo。图3-6(a)所示页面对应MainActivity,图3-6(b)所示页面对应NewActivity,图3-6(c)所示页面对应ParamsActivity,图3-6(d)所示页面对应ReturnParamsActivity。学习者可暂不关心页面的细节,直接使用可视化工具拖曳生成如上功能的页面即可。
(2)为MainActivity的按钮一添加事件,使用startActivity()方法,跳转到NewActivity。
(3)为MainActivity的按钮二添加事件,将输入的书名和价格装入Intent对象,使用startActivity()方法跳转到ParamsActivity中。在ParamsActivity中获取参数值,展示出来。
(4)为MainActivity的按钮三添加事件,用startActivityForResult()方法跳转到ReturnParamsActivity。在它内部把输入的值装入Intent,执行finish()方法返回,并触发MainActivity的onActivityResult()方法接收数据并展示出来,具体细节详见代码。
(1)首页面类MainActivity的代码如下:
(2)与图3-6(c)所示页面对应的类ParamsActivity的代码如下:
(3)与图3-6(d)所示页面对应的类ReturnParamsActivity的代码如下:
案例运行效果如图3-6所示。学习者也可以下载源码,尝试在模拟器或者真机中测试运行。