前言
Activity是Android中最常见的,也是最重要的应用组件,是提供用户完成指令的窗口。调用setContentView(View)方法来指定一个显示的界面,并采用Activity栈的方式来管理Activity。建立自己的Activity需要继承Activity基类。基类的种类有以下这些
一、Activity的形态
Activity拥有多种形态,在多种形态将进行切换,以此控制自己的生命周期
Activity/Running (运行状态)
处于Activity栈的最顶层,处于前台进程,与用户进行交互Paused (暂停状态)
Activity失去焦点,处于可视进程。被一个非全屏的Activity或者透明的Activity放置在栈顶,Activity转化为Paused形态,失去与用户交互能力,所有状态信息成员变量仍保持,内存极低时被系统回收Stopped (停止状态)
被另一个Activity完全覆盖,进入Stopped形态,不可见,所有状态信息成员变量仍保持。处于后台进程Killed (销毁状态)
Activity被系统回收或者Activity从未被创建过。
二、Activity的生命周期
·
群英传中有说,Android的生命状态中有三个状态是稳定(Resumed、Paused、Stopped),其他状态是过渡状态
- onCreate(Bundle savedStatedStatus)
创建Activity时被回调,只会被调用一次 - onStart()
启动Activity时被回调 onRestart()
重新启动时回调,也就是activity调用onStop()后,由后台进程转到前台进程,Activity再次变得可见时回调onResume()
onStart()后一定会调用onResume()。另外,当Activity调用onPaused()后,也就是处于可视进程,转到前台进程时调用onResume()onPaused()
暂停Activity时调用,也就是由前台进程转化为可视进程。另外提一点, 记录资源状态信息往往是在该方法中实现onStop()
Activity变为完全不可见,处于后台进程onDestroy()
Activity被销毁时调用,只会调用一次
三、Android的4种加载模式
Android采用Task管理多个Activity,一个App启动时,如果当前系统不存在该App的任务栈Task,则系统会创建一个Task,然后启动这个应用的第一个Activity,第一个Activity需要AndroidMainnifest中配置一下信息
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
正常情况中栈采用后进先出(Last In First Out)方式,先启动的Activity放在栈底,后启动的Activity放在栈顶。但我们可以采用不同的启动模式来打破这种情况。在AndroidMainifest文件中android:launchMode或Intent的flag设置不同的加载模式
standard模式
默认的启动模式,每次为目标Activity创建一个新的实例,并置于栈顶。该模式不会启动新的TasksingleTop模式
当将要启动的Activity已经位于栈顶时,系统不会重新创建一个新的目标Activity实例,而是直接复用已有的Activity实例,但如果目标Activity没有位于栈顶,则创建一个新的实例,与standard模式一致singleTask模式
Task中只含目标Activity唯一的一个实例,采用singleTask模式,系统检测栈中是否存在当前需要启动的Activity,如果存在,将目标Activity实例以上的Activity实例全部销毁,将目标Activity实例置于栈顶。
有趣的是,启动的目标Activity实例已经存在于另一个Task中时,启动后,存在目标Activity实例的Task将一并切换到前台。如图
- singleInstance
采用该模式的Activity,启动它时会重新创建一个Task,并且该栈只包含该Activity。
另外,当应用A启动了该Activity实例,如果应用B也要调用该Activity,则无须创建,两个应用共享该实例,常用于需要与程序分离的界面。
Intent Flag启动模式
FLAG_ACTIVITY_NEW_TASK
使用一个新的Task来启动Activity,通常用于Service中启动,因为Service不存于Activity栈中FLAG_ACTIVITY_SINGLE_TOP
与 android:launchMode=”singleTop” 效果一致FLAG_ACTIVITY_CLEAR_TOP
与 android:launchMode=”singleTask” 效果一致FLAG_ACTIVITY_NO_HISTORY
当该Activity启动其他Activity后,该Activity消失FLAG_ACTIVITY_CLEAR_TASK
这个标记,将会导致任何用来放置该activity的已经存在的task里面的已经存在的activity先清空,然后该activity再在该task中启动,也就是说,这个新启动的activity变为了这个空task的根activity.所有老的activity都结束掉。该标志必须和FLAG_ACTIVITY_NEW_TASK一起使用。
四、Activity间传递信息
Activity之间的通信是必不可少的一部分,常用的通信方式有以下几种
- Intent
静态变量:适用于不可序列化的且简单的对象
全局变量 及Application
Android系统剪切板
本地化存储方式
- SharedPreference
- SQLite
- File
onActivityResult回调监听
通过重写该方法获取数据Andorid组件
- Broadcast方式
- Service方式
EventBus
EventBus 是一款针对Android的发布以及订阅事件总线,使用它可以很方便的进行信息传递
Intent
是目前最常见的信息传递方式,Intent 即意图:当一个Activity需要启动另一个Activity时,程序并没有直接告诉系统需要启动哪个Activity,而是通过Intent表达自己的意图。
通过Intent.putExtra方法可以将简单数据类型或可序列化对象保存在Intent对象中,然后在另一个Activity中使用getInt、getString等方法获得这些数据
Intent可传递的数据类型
8中基本数据类型及其数组
String(String实现了Serializable)/CharSequence实例类型的数据及其数组
实现了Plarcelable的对象及其数组
实现了Serializable的对象及其数组(File在Java里也是类,在Android中实现了Serializable接口)
五、Activity现场保存状态
Activity调用了onPause和onStop()的进程仍然会保存在内存当中,但内存不足时,它所在的线程仍然会被终止。因此我们需要考虑保存Activity所有信息和状态,一般会采用两种方法实现
onPause()
若向数据库中插入记录等,保存持久化数据的操作,适用于调用onPause()方法的时候实现onSaveInstanceState()
该方法适合保存瞬态数据, 比如UI控件的状态, 成员变量的值等
onSaveInstanceState()方法接受一个Bundle类型的参数, 开发者可以将状态数据存储到这个Bundle对象中,以保证该状态在onCreate(Bundle)或者onRestoreInstanceState(Bundle)(传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。
执行顺序:在当前Activity被销毁之前会调用onSaveInstanceState,然后销毁当前Activity,创建新的Activity之后会调用onCreat方法之后会紧接着调用onRestoreInstanceState
参考资料
Android Activity原理以及其子类描述
Activity详细总结
Android群英传(徐宜生·著)
Android 消息通信之Activity间消息传递