Android四大组件
lay a solid foundation
夯实基础
Activity
生命周期
1.与Fragment进行绑定时的生命周期变动
SDK28 模拟器28
进入Activity,绑定Fragment,然后点击返回键之后
进入Activity,绑定Fragment,点击home,然后重新进入,再点击返回
进入Activity,绑定Fragment,点击home,然后直接打开任务管理器kill掉任务
为什么onDestroy没有执行?
用一句话概述
不要在onStop,onDestory中保存重要数据;最近任务栏清除app,app的onDestory不会掉用是因为该Binder调用是非阻塞的,导致App被杀死,所以onDestory没来得及调用
2.特殊情况下的生命周期
上面是普通情况下Activity生命周期的一些流程,但是在一些特殊情况下,Activity的生命周期的经历有些异常,下面就是两种特殊情况。
①横竖屏切换
在横竖屏切换的过程中,会发生Activity被销毁并重建的过程。
在了解这种情况下的生命周期时,首先应该了解这两个回调:onSaveInstanceState和onRestoreInstanceState。
在Activity由于异常情况下终止时,系统会调用onSaveInstanceState来保存当前Activity的状态。这个方法的调用是在onStop之前,它和onPause没有既定的时序关系,该方法只在Activity被异常终止的情况下调用。当异常终止的Activity被重建以后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象参数同时传递给onRestoreInstanceState和onCreate方法。因此,可以通过onRestoreInstanceState方法来恢复Activity的状态,该方法的调用时机是在onStart之后。其中onCreate和onRestoreInstanceState方法来恢复Activity的状态的区别:onRestoreInstanceState回调则表明其中Bundle对象非空,不用加非空判断。onCreate需要非空判断。建议使用onRestoreInstanceState。
横竖屏切换的生命周期:onPause()->onSaveInstanceState()-> onStop()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState->onResume()
可以通过在AndroidManifest文件的Activity中指定如下属性:
android:configChanges = "orientation| screenSize"
来避免横竖屏切换时,Activity的销毁和重建,而是回调了下面的方法:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); }
②资源内存不足导致优先级低的Activity被杀死
Activity优先级的划分和下面的Activity的三种运行状态是对应的。
(1) 前台Activity——正在和用户交互的Activity,优先级最高。
(2) 可见但非前台Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户交互。
(3) 后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。
当系统内存不足时,会按照上述优先级从低到高去杀死目标Activity所在的进程。我们在平常使用手机时,能经常感受到这一现象。这种情况下数组存储和恢复过程和上述情况一致,生命周期情况也一样。
3.Activity的三种运行状态
①Resumed(活动状态)
又叫Running状态,这个Activity正在屏幕上显示,并且有用户焦点。这个很好理解,就是用户正在操作的那个界面。
②Paused(暂停状态)
这是一个比较不常见的状态。这个Activity在屏幕上是可见的,但是并不是在屏幕最前端的那个Activity。比如有另一个非全屏或者透明的Activity是Resumed状态,没有完全遮盖这个Activity。
③Stopped(停止状态)
当Activity完全不可见时,此时Activity还在后台运行,仍然在内存中保留Activity的状态,并不是完全销毁。这个也很好理解,当跳转的另外一个界面,之前的界面还在后台,按回退按钮还会恢复原来的状态,大部分软件在打开的时候,直接按Home键,并不会关闭它,此时的Activity就是Stopped状态。
4.Activity启动模式
Android的启动模式一共有4种,默认情况我们使用的是标准模式。
通过在 里添加 **android:launchMode **即可设置相应的启动模式~
- 标准模式(standard)
- 栈顶复用模式(singleTop)
- 栈内复用模式(singleTask)
- 单例模式(singleInstance)
4.1启动模式的结构——栈
Activity的管理是采用任务栈的形式,任务栈采用“后进先出”的栈结构。
标准模式
活动的默认启动模式,简单来说,在你不指定启动模式的情况下,你每打开一个新的Activity,新的Activity都会加入你的返回栈并且处于栈顶状态。这样当你点返回的时候就是一层一层退栈。遵循后进先出的原则。
栈顶复用模式
有些时候,你会觉得 standard 模式有点别扭,明明已经在栈顶了,如果是相同的Activity还要在启动时创建一次,不麻烦吗。所以singleTop 就可以解决你这个问题,如果在启动时发现返回栈的栈顶已经是当前Activity,则不会再次创建,而是直接复用。
栈内复用
与栈顶复用不同的是,**singleTask会在启动Activity时会先检查栈内是否有此Activity,如果有,则将这个Activity之前的栈全部退栈,这样要启动的Activity就成了栈顶,免去了重新创建。但是如果当前不存在此Activity,则会创建一个新的Activity来管理此活动。**所以要注意使用时的需求。
单例模式
单例模式?设计模式,字名一样,意思从某种程序上来说也差不多,全局唯一。
与上面三种不同的是,指定为 singleInstance 的模式,在启动的时候会启用一个新的返回栈来管理此活动,而且只会创建一次(当然,如果你kill掉之后再启动就另当别论啦),如此一来,全局独立并唯一。
Service
Service是Android中实现程序后台运行的解决方案。但是需要注意的是,Service默认不会运行在子线程,它也不允许在一个独立进程中,它同样执行UI操作。因此不要在Service中执行耗时操作。除非Service中创建了子线程来完成耗时操作。
- IPC: 简称进程间通信,是指两个进程之间进行数据交换的过程。
- AIDL :用于生成可以在Android设备上两个进程之间进行IPC的代码。如果在一个进程中(比如Activity)要调用另一个进程中(比如Serveice)对象的操作,就可以使用AIDL生成可序列化的参数。
关于AIDL 及 IPC本篇不会过多涉及。先了解广度即可,在以后我会逐渐涉及并记录。
1. 按运行地点分类:
1.1 本地服务(Local Service)
该服务依附于主线程。
而不是独立进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。所以 bindService 会方便很多。
需要记住的是 主进程被Kill后(onbindStart),服务便会终止。
1.2 远程服务(Remote Service)
> 该服务是独立进程,对应进程名格式为所在包名加上指定的 android:process 字符串。由于是独立进程,因此在Activity所在进程被kill时,该服务依然运行,不受影响。,>,> 但需要注意的是:因为该服务是独立进程,会占用一定资源,并且使用 AIDL 进行 IPC会稍微麻烦。
2 按运行类型分类
2.1 前台服务:
会在通知栏显示 常存的 Notification
当服务被终止时,通知栏的 Notification也会消失,对于用于有一定的提醒作用,比如音乐播放器通知栏旁边的 x 号点击之后。(当然这里指的是少数播放器,并不是所有播放类软件都会带)
2.2 后台服务:
默认的服务即为后台服务,即不会在通知栏显示 常存的 Notification
服务被终止时用户无法察觉,如天气的更新,数据的同步等等。
3 按使用方式分类
3.1 startService启动的服务
主要用于启动一个服务执行后台任务,不进行通信。停止服务使用 onstopService.
3.2 binService启动的服务
与服务通信绑定时使用的方法,停止服务使用 unbindService.
3.3 同时使用startService和bindService启动
停止服务应同时使用 stopService 与 unbindservice