Android Activity
Activity 是与用户交互的接口
Android 系统通过 Activity 栈的形式管理 Activity
Activity 4 种形态
- Active 运行状态:Activity 处于栈顶,可见,可以和用户进行交互
- Paused 暂停状态:不处于栈顶,可见但不可交互,失去焦点被非全屏 Acitivty 挡住
- Stopped 停止状态:不处于栈顶并且完全不可见,被另一个 Activity 完全覆盖
- Killed 销毁状态:从返回栈中移除,系统回收掉
Activity 生命周期
以下是 Activity A 启动 Activity B 时的操作发生顺序:
- Activity A 的
onPause()
方法执行。 - Activity B 的
onCreate()
、onStart()
和onResume()
方法依次执行(Activity B 现在具有用户焦点)。 - 然后
- 如果 Activity A 在屏幕上不再显示,其
onStop()
方法执行。 - 如果 Activity B 为对话框或者透明窗口,并且局部覆盖了 Activity A,其
onStop()
方法不会执行
- 如果 Activity A 在屏幕上不再显示,其
当 Activity 开始停止时,系统会调用 onSaveInstanceState()
方法,将状态信息保存到实例状态 Bundle 中。
当用户显式关闭 Activity 时,或者在其他情况下调用 finish()
时,系统不会调用 onSaveInstanceState()
。
异常状态下的状态更改
如果系统因系统限制(例如配置变更或内存压力)而销毁 Activity,系统会记住它曾经存在过。如果用户尝试回退到该 Activity,系统将使用一组描述 Activity 销毁时状态的已保存数据新建该 Activity 的实例。
配置发生更改:最显著的例子或许是横屏和竖屏之间的屏幕方向变化。其他情况,如语言或输入设备的改变等,也可能导致配置更改。
重建先前被销毁的 Activity 后,可以从系统传递给 Activity 的 Bundle 中恢复保存的实例状态。onCreate()
和 onRestoreInstanceState()
回调方法均会收到包含实例状态信息的相同 Bundle。
onRestoreInstanceState()
方法会在 onStart()
之后调用,onCreate()
中的 Bundle 可能为 null,onRestoreInstanceState()
方法中的 Bundle 不为 null。
Activity 之间通信
- Intent/Bundle
- 类静态变量
- 全局变量
- EventBus
- 广播
Activity 与 Fragment 通信
Activity 将数据传递给 Fragment
- LiveData
Fragment 将数据传递给 Activity
- 在 Fragment 中定义一个内部回调接口,在 Activity 中实现接口
- Fragment 的方法
onAttach()
,检查 Activity 是否实现对应接口 - 调用
onDetach()
方法,将传递进来的 Activity 对象释放掉
Activity 与 Service 数据通信
绑定服务,利用 ServiceConnection 类
在 Service 中创建一个 Bindler 对象:
class MyService : Service() { |
新建一个 DownloadBinder 类并继承自 Binder,在其内部提供方法。接着在 MyService 中创建 DownloadBinder
的实例,然后在 onBind()
方法中返回这个实例。
class MainActivity : AppCompatActivity() { |
先创建一个 ServiceConnection 的匿名类实现,并在里面重写了 onServiceConnected()
方法和 onServiceDisconnected()
方法。onServiceConnected()
方法会在 Activity 与 Service 成功绑定的时候调用,而 onServiceDisconnected()
方法只有在 Service 的创建进程崩溃或者被杀掉的时候才会调用,这个方法不太常用。那么在 onServiceConnected()
方法中,又通过向下转型得到了 DownloadBinder 的实例。可以在 Activity 中根据具体的场景来调用 DownloadBinder 中的任何 public 方法。
调用 bindService()
方法将 MainActivity 和 MyService 进行绑定。bindService()
方法接收 3 个参数,第一个参数就是刚刚构建出的 Intent 对象,第二个参数是前面创建出的 ServiceConnection 的实例,第三个参数则是一个标志位,这里传入 IND_AUTO_CREATE
表示在 Activity 和 Service 进行绑定后自动创建 Service。这会使得 MyService 中的 onCreate()
方法得到执行,但 onStartCommand()
方法不会执行。调用 unbindService()
方法可以解除绑定。
简单通信,利用 Intent 进行传值
只能传递简单数据,性能没有优势
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { |
定义一个 callback 接口来监听服务中的进程的变化
在 Service 中添加接口,在 Binder 中定义返回 Service 对象的方法
在 onServiceConnected()
方法中利用 IBinder 对象实现 Service 中的接口,实现的方法是在子线程中,需要使用 handler 更新 UI。
Activity 启动模式
standard (默认模式)
- 在不指定启动模式的前提下,系统默认使用该模式启动 Activity
- 每次启动一个 Activity 都会重新创建一个新的实例
- 会依次调用
onCreate()
,onStart()
,onResume()
方法
singleTop (栈顶复用)
如果当前任务的顶部已存在 Activity 的实例,则系统会通过调用其onNewIntent()
方法来将 intent 转送给该实例,而不是创建 Activity 的新实例。如果不在顶部则会在堆栈中添加新实例。应用场景:IM 对话框、新闻客户端推送、接收通知启动的内容显示页面等
singleTask (栈内复用)
- 根据任务相关性
taskAffinity
(默认为包名) 寻找是否存在一个对应名字的任务栈 - 如果不存在则会创建一个新的 Task
- 如果存在则得到该任务栈,查找该任务栈中是否存在该 Activity 实例
- 如果存在实例则将该实例上方所有 Activity 实例出栈,然后回调该实例中的
onNewIntent()
方法 - 如果不存在则创建一个新的 Activity 实例
- 如果存在实例则将该实例上方所有 Activity 实例出栈,然后回调该实例中的
应用场景:应用主界面
- 根据任务相关性
singleInstance
与singleTask
相似,唯一不同的是系统不会将任何其他 Activity 启动到包含该实例的任务中。该 Activity 始终是其任务唯一的成员;由该 Activity 启动的任何 Activity 都会在其他的任务中打开。应用场景:呼叫来电、闹钟响铃界面等