Android-四大组件

220 阅读6分钟

记录

日期说明
2023/2/18首次创建

总纲

关于四大组件的相关概念

Activity

生命周期

  • 整个生命周期只会被调用一次,适合重量级资源操作
    • onCreate
      • 触发时机:页面创建
    • onDeatroy
      • 触发时机:页面finish;配置改变(屏幕旋转等)
  • 可见周期(并不是前台):适合中量操作
    • onStart
      • 可见,准备去前台
      • 从内存中调用activity对象信息
    • onStop
      • 不可见,已经在后台
      • 此时activity对象会被保存在内存中,包括状态信息,成员信息
  • 前台周期(获得焦点,可以交互):适合轻量级操作(开启动画、独占设备)
    • 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及以上,多个应用以多窗口运行,因为任何时刻只能聚焦在一个应用上,其他的应用会被暂停

启动方式

  • 显示启动
  • 隐式启动
  • 包名启动

横竖屏切换

  • 设置横竖
    • 在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进行全局配置
      1. style.xml中定义
      2. 修改theme
      3. 在application中设置
    • 使用transitionManger
    • 使用addOnPreDrawListener
  • 隐藏actionBar
    1. getActionBar.hide方法
    2. requestWindowFeature(Window.FEATURE_NO_TITLE)方法
    3. @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
  • 常用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

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
    1. onCreate
    2. onStartCommand
    3. onDestroy
  • bind
    1. onCreate
    2. onBInd
    3. onUnbind
    4. onDestroy

intentService

  • 继承于Service,异步执行耗时操作

Activity与Service通信

  • 通过BInder对象
  • 通过broadcast

Binder机制

  • 流程
    1. client调用代理proxy接口的方法,然后代理将传递的参数打包为parcel对象
    2. 代理把parcel对象发送给内核中的Binder driver
    3. 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来管理广播
    1. LocalBroadcastManager.getInstance获取实例
    2. registerReceiver注册广播
    3. sendBroadcast发送广播
    4. unRegisterReceiver注销广播
  • 注意
    1. **本地广播无法通过静态注册来接收!**相比系统全局广播更加高效
    2. 在广播中启动activity时,需要为intent加上FLAG_ACTIVITY_NEW_TASK标识,因为需要一个栈来存放新打开的activity
    3. 广播中弹出alertDialog时,需要设置对话框的类型为TYPE_SYSTEM_ALERT,否则无法弹出
    4. 广播内禁止进行长耗时操作

ContentProvider

URI

  • [A][B][C][D]
    • A: 协议名称,必须是content://
    • B: 组件的android:authority属性值,必须保证全局唯一
    • C: 资源相对路径,描述要访问的资源的类型
    • D: 资源ID,描述要访问的具体资源