记录
| 日期 | 说明 |
|---|---|
| 2023/2/18 | 首次创建 |
总纲
关于四大组件的相关概念
Activity
生命周期
- 整个生命周期只会被调用一次,适合重量级资源操作
- onCreate
- 触发时机:页面创建
- onDeatroy
- 触发时机:页面finish;配置改变(屏幕旋转等)
- onCreate
- 可见周期(并不是前台):适合中量操作
- onStart
- 可见,准备去前台
- 从内存中调用activity对象信息
- onStop
- 不可见,已经在后台
- 此时activity对象会被保存在内存中,包括状态信息,成员信息
- onStart
- 前台周期(获得焦点,可以交互):适合轻量级操作(开启动画、独占设备)
- onResume
- onPause
- 注意不能进行耗时操作。因为会影响下一个activity的启动速度。它执行完了才会开启下一个。
- 大多数情况下,onPause都会执行,适合处理数据持久化
- 完成onPause方法不意味着activity离开pause状态,相反,activity会一直保存这个状态,直到恢复或者彻底不可见
- 重新启动
- onRestart
- 非常重量级,与界面无关的资源操作,可以放到application的onCreate
- 横竖屏切换
- 避免activity被销毁并重建:android:configChanges="orientation|screenSize"
- 系统只在销毁后有机会再次展示才会调用onSaveInstanceState和onRestoreInstanceState。资源内存不许杀死也会触发。其他情况不会触发
graph TD
onPause --> onSaveInstanceState --> onStop --> onDestroy --> onCreate --> onStart --> onRestoreInstanceState --> onResume
- 特殊情况
- 只onPause,五onStop
- 新activity为半透明或者悬浮在旧的上面,旧的只到onPause
- 新activity非finish异常退出,本身知道onPause
- 7.0及以上,多个应用以多窗口运行,因为任何时刻只能聚焦在一个应用上,其他的应用会被暂停
- 只onPause,五onStop
启动方式
- 显示启动
- 隐式启动
- 包名启动
横竖屏切换
- 设置横竖
- 在androidManifest.xml中为Activity添加一个属性,android:ScreenOrientation
- 加载不同布局
- 创建两个布局文件在layout-land和layout-port,布局文件名相同,系统可以自动加载
- 手动加载
- 状态保存
- onCreate(Bundle svaedInstanceState)
- onSaveInstanceState(Bundle outState)
- onRestoreInstanceState(Bundle svaedInstanceState)
交互
- 数据传递
- Bundle:限制带下为0.5M,超过会报错
- 使用startActivityForResullt(intent, requestCode)
- 重写onActivityResult(requestCode, resultCode, data)
- 调用setResult(resultCode, data)
- 过场动画
- overridePendingTransition(inAnim, outAnim)
- style进行全局配置
- style.xml中定义
- 修改theme
- 在application中设置
- 使用transitionManger
- 使用addOnPreDrawListener
- 隐藏actionBar
- getActionBar.hide方法
- requestWindowFeature(Window.FEATURE_NO_TITLE)方法
- @style/AppTheme.NoActionBar设置
task管理
- 任务是指执行特征作业时与用于交互的一系列activity
- 清空栈
- alwaysRetaionTaskState
- clearTaskOnLaunch
- finishOnTaskLaunch
加载模式
- standard
- 默认模式,每次启动都会实例化一个activity
- singleTop
- 如果栈顶有,就直接调用;否则就创建实例化。
- 等效于SINGLE_TOP
- onPause --> onNewIntent --> onResumt
- singleTask
- 如果task里有,就把它上面的activity都destroy弹出,让他出现在栈顶,没有就会创建实例
- 等效于NEW_TASK ?
- 适合创建需要大量系统资源的activity
- onPause --> onNewIntent --> onResumt
- singleInstance
- 他启动的activity单独运行于零一个task
- 加载模式的指定方法
- 在清单文件AndroidManifest中声明
- 可以为singleInstance等,无法直接CLEAT_TOP
- 调用startActivity是,使用Intent标识
- 优先级更高,但是不能设置为singleInstance
- 在清单文件AndroidManifest中声明
- 常用FLAG
- FLAG_ACTIVITY_CLEAR_TASK
- 在同一个栈中,单独使用,没有效果
- 结合NEW_TASK,如果新activity是standard模式,旧activity会destroy;如果新的已经存在就会被destroy,重新onCreate
- FLAG_ACTIVITY_SINGLE_TOP
- 等同于singleTop
- FLAG_ACTIVITY_NEW_TASK
- 如果在不同的task中,直接使用,重复触发不会页面跳转
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_CLEAR_TASK
taskAffinity属性
- 标识一个activity所需要的任务栈的名字
关闭
- finish: 不会立即释放内存,遵循android内存管理机制,会走生命周期
- exit: 立即释放当前activity所占用的资源,不会走生命周期
- 范围:只会影响当前程序
- 方式:停止程序的虚拟机
- System.exit(0)表示是正常退出;
- System.exit(1)表示是非正常退出,通常这种退出方式应该放在catch块中。
- killProcess: 立即释放当前activity所占用的资源,不走生命周期
- 范围:杀掉所有pid一样的进程
- 方式:通过pid杀死进程
- 由于ActivityManager时刻监听着进程,一旦发现进程被非正常Kill,它将会试图去重启这个进程
- restartPackage: 结束整个app,包括service等其他组件,2.2之后弃用
特殊Activity
- 半透明activity
- 使用Theme.Translucent,activity必须是extends Activity而不是AppCompatActivity
- 自定义style,android:windowIsTranslycent=true
- 悬浮activity
- android:windowIsFloating=true
Service
生命周期
- create
- onCreate
- onStartCommand
- onDestroy
- bind
- onCreate
- onBInd
- onUnbind
- onDestroy
intentService
- 继承于Service,异步执行耗时操作
Activity与Service通信
- 通过BInder对象
- 通过broadcast
Binder机制
- 流程
- client调用代理proxy接口的方法,然后代理将传递的参数打包为parcel对象
- 代理把parcel对象发送给内核中的Binder driver
- server读取Binder driver中的请求数,如果是发送给自己的,解析parcel对象,处理并返回结果
- 优势
- 可靠,安全,高性能
- AIDL
- IPC是跨进程通信,android通过Binder机制实现IPC,这个机制使用的接口语言是AIDL
- 注意
- 接口名词需要与aidl文件名相同
- 接口和方法前面不能加访问权限修饰符
- aidl传递的数据类型必须是序列化的
启动方式
- 显示
- new Intent(context, service.class)
- 隐式
- intent.setAction
- android 5.0不允许隐式启动,这种方法必须追加intent.setPackage ???
BroadcastReceiver
类型
- 标准广播
- 完全异步执行的广播,所有的额接收器几乎在同一时间收到这条通知
- 有序广播
- 同步执行的广播,同一时间只有一个广播接收器能收到,当这个接收器执行完之后才会发送给下一个,如果先接收的截断了广播,后续就无法接收到了
注册方式
- 动态注册
- 在代码中指定intentFilter,然后添加action进行监听
- 静态注册
- 在androidManifest中指定IntentReceiver,可以在程序未启动的情况下接收广播。android 8.0及以上无法接收到xml注册的静态广播
本地广播
- 用法:使用LocalBroadcastManager来管理广播
- LocalBroadcastManager.getInstance获取实例
- registerReceiver注册广播
- sendBroadcast发送广播
- unRegisterReceiver注销广播
- 注意
- **本地广播无法通过静态注册来接收!**相比系统全局广播更加高效
- 在广播中启动activity时,需要为intent加上FLAG_ACTIVITY_NEW_TASK标识,因为需要一个栈来存放新打开的activity
- 广播中弹出alertDialog时,需要设置对话框的类型为TYPE_SYSTEM_ALERT,否则无法弹出
- 广播内禁止进行长耗时操作
ContentProvider
URI
- [A][B][C][D]
- A: 协议名称,必须是content://
- B: 组件的android:authority属性值,必须保证全局唯一
- C: 资源相对路径,描述要访问的资源的类型
- D: 资源ID,描述要访问的具体资源