Activity学习笔记

本篇文章主要讲述Activity的生命周期、启动方式、回传值以及状态栏与标题栏显示与否,有关回退栈和Activity之间通信在下一片文章中再详细将探讨。

Activity的生命周期

在 android 中,Activity 的生命周期交给系统统一管理。事实上它包含了四种状态:

  1. Active/Runing一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
  2. Paused 当 Activity 被另一个透明或者 Dialog 样式的 Activity 覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。
  3. Stoped 当 Activity 被另外一个 Activity 覆盖、失去焦点并不可见时处于 Stoped状态。
  4. Killed Activity 被系统杀死回收或者没有被启动时处于 Killed状态。

activity_state

如上所示,Android 程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就时说程序员可以启动一个 Activity,但是却不能手动的“结束”一个 Activity。当你调用 Activity.finish()方 法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态。例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当我们调用 Activity2.finish()方法时,Activity Manager 重新激活 Activity1 并入栈,Activity2 从 Active 状态转换 Stoped 状态,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2 返回的数据通过 data参数返回给 Activity1。

activity_lifecycle

上图就是Activity完整生命周期,事实上包含了生命周期中的三个嵌套循环

  • entire lifetime (整个生命周期)一个Activity整个生命周期,存在于onCreate()方法和onDestroy()调用之间。你的Activity应该在onCreate()方法里执行设置“全局”状态(如定义布局)。并在onDestroy()方法里释放所有剩余资源。例如,如果你的活动有一个线程在后台运行下载网络数据,它可以在onCreate()中创建该线程,然后在onDestroy()中停止线程。
  • visible lifetime(可见生命周期)一个Activity可见生命周期,存在于onStart()和onStop()调用之间。在此期间,用户可以看到屏幕上的activity并与之交互。当一个其他的Activity启动,并且这个Activity完全不可见的时候,onStop()方法就会被调用。在这两个方法,你可以保持该Activity需要展示给用户的资源。例如,您可以在onStart()方法里注册一个BroadcastReceiver来监控你的UI的变化,并在onStop()方法里注销它。在整个生命周期的活动中,系统可能会调用onStart()和onStop()多次,因为活动之间交替进行隐藏或显示给用户。
  • foreground lifetime(前台生命周期)一个Activity前台生命周期,存在于onResume()和onPause()调用之间。在这段时间里,这个Activity在其他所有Activity的前面,拥有用户输入焦点。一个Activity可以经常在前台状态发生转换—比如,当设备休眠或者弹出了个对话框。因为经常会发生转换,所以在这两个方法之间的代码应该是轻量级的,防止导致其他转换变慢使得用户需要等待。

返回键、home键、电源键Activity生命周期执行顺序

  • 返回键当Activity处于运行状态时点击返回键,相应的代码执行顺序onPause()–>onStop()–>onDestory();如果当前activity正同用户交互时点击返回键,相当于销毁了当前Activity。
  • home键处于运行状态的Activity当用户点击home键时,相应的代码执行顺序onPause()–>onStop(),如果这时还没被当前系统回收销毁,用户重新进入应用,相应的代码执行顺序onRestart()–>onStart()–>onResume();
  • 电源键电源键同home键的执行顺序一致,但是有一点需要注意,就是如果点击电源键之后手机锁屏了,这时候回来重新点击电源键虽然用户没有开启锁屏,但是这时候已经执行了onResume()方法。

横竖屏切换对生命周期的影响

正常情况下如果用户执行了横竖屏切换代码的执行顺序:onPause()–>onStop()–>onDestory–>onCreate()–>onStart()–>onResume();Activity已经被销毁重新创建了一次,这种情况是很多应用都不想看到的效果。最简单的就是视频播放,当用户正在看到一半的时候,横竖屏不小心切换了一下,视频进度就又重新开始,这很显然是让人很头痛的一件事,那么怎么解决这一问题呢。

方式一:采用onSaveInstanceState方法来保存现场,Activity中有这样一个函数protected void onSaveInstanceState(Bundle outState),用这种方式就可以保存现场了,我们知道在Activity创建时需要执行onCreate方法,里面又一个 Bundle类型的参数savedInstanceState,这个参数就是为了恢复现场用的,下面是一个简单的小示例核心代码:

这中方式相当繁琐复杂,试想一下如果我们正在一个列表页面翻了数页才找到一个需要的资源,这时后点击下载,横竖屏切换一下,用这种方式来保存状态,这个复杂程度可不是一般的复杂,所以不建议采用这种方式保存现场。

方式二:直接在清单文件中配置一下就可以,简单方面直接有效,配置一下其余的事情都让系统做就行了,在Activity注册的时候添加上这样一个属性就可以android:configChanges=”orientation|screenSize”,所以更建议采用这种方式来保存现场

Activity的启动方式

这篇文章讲的启动方式并不设置回退栈的相关信息,只是很简单的讲一下从一个Activity跳转到另一个Activity是如何跳转的,事实上是两种方式:显示启动和隐式启动。

显示启动

显示启动的四种写法事实上是殊途同归,最终代码都转化为了方式三

隐式启动

显示启动通过指定目标Activity的类名启动

隐式启动通过指的定Action动作启动指定的Activity

显示和隐式的应用场景

显示意图一般用于启动同一个应用下的Activity,隐式意图一般用在启动不同应用下的Activity

Activity请求回传值

Activity回传值应用场景也挺多的,比如我们拍照选择手机中的图片或者选择通讯录中的电话号码。

Activity一些技巧

锁定屏幕方向

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

全屏的Activity

全屏Activity就是状态栏都不显示,最常用的就是视频播放页面,可以在其 onCreate()方法中添加如下代码实现:

注意:requestWindowFeature(Window.FEATURE_NO_TITLE)必须放在setContentView方法前面否则就会抛出异常,原因就在于在setContentView中会依据Feature等style theme创建不同的窗口修饰布局文件,去除标题栏就是设置无标题Feature的,所以必须放在setContentView前面。

示例截图以及源代码下载

activity_demo

下载demo

本文地址www.sunnyang.com/233.html

发表评论