要点提炼|开发艺术之四大组件

作者: 厘米姑娘 | 来源:发表于2017-12-27 17:12 被阅读1972次

    提到四大组件大家肯定再熟悉不过了,本篇侧重于对四大组件工作过程的分析:

    • 概述
    • 工作过程
      • Activity
      • Service
      • BroadcastReceiver
      • ContentProvider

    1.概述

    a.Activity

    • 类型:展示型组件。
    • 作用:展示一个界面并和用户交互。
    • 使用:
      • 需要在AndroidManifest中注册。
      • 需要借助Intent启动,两种方式:
        • 显示Intent:
          Intent intent=new Intent(xxx.this,xxx.class); startActivity(intent);
        • 隐式Intent:
          Intent intent=new Intent(); intent.setAction(xxx); intent.addCategory(xxx); startActivity(intent);
      • 四种启动模式:
        • standard:标准模式
        • singleTop:栈顶复用模式
        • singleTask:栈内复用模式
        • singleInstance:单实例模式
      • 对用户而言是可见的。
      • 通过finish()结束一个Activity。

    相关基础入门之Activity篇开发艺术之Activity

    b.Service

    • 类型:计算型组件。
    • 作用:在后台执行一系列计算任务,耗时的后台计算建议在单独的线程中执行。
    • 使用:
      • 需要在AndroidManifest中注册。
      • 需要借助Intent启动:
        Intent intent = new Intent(xxx.this, xxx.class); startService(intent);
      • 两种运行状态:
        • 启动状态:通过startService()
        • 绑定状态:通过bindService()
      • 用户无法感知。
      • 通过unBindService()stopService()完全停止一个Service。

    相关基础入门之Service篇

    c.BroadcastReceiver

    • 类型:消息型组件。
    • 作用:在不同的组件乃至不同的应用之间传递消息。
    • 使用:
      • 两种注册方式:
        • 动态注册:通过Context.registerReceiver()& Context.unRegisterReceiver(),必须要应用启动才能注册并接收广播。
        • 静态注册:在AndroidManifest文件中注册,不需要启动应用即可接收广播。
      • 需要借助Intent发送广播:
        Intent intent = new Intent("xxx"); sendBroadcast(intent);
      • 四种广播类型:
        • 普通广播
        • 有序广播
        • 本地广播
        • 粘性广播
      • 用户无法感知。
      • 没有停止概念。

    相关基础入门之BroadcastReceiver篇

    d.ContentProvider

    • 类型:共享型组件。
    • 作用:向其他组件乃至其他应用共享数据。
    • 使用:
      • 需要在AndroidManifest中注册。
      • 无需借助Intent启动。
      • 四种操作:注意需要处理好线程同步
        • insert():添加数据
        • update():更新数据
        • delete():删除数据
        • query():查询数据
      • 用户无法感知。
      • 无需手动停止。

    相关基础入门之ContentProvider篇IPC方式之ContentProvider
    考考自己android四大组件的运行状态


    二.工作过程

    由于相关源码非常多,这里借用@amurocrash的UML图来提炼流程更为直观,另附相关源码分析的文章供大家详细了解。

    a.Activity

    Activity启动过程流程图:

    Activity启动过程

    结论

    • ActivityManagerService、ApplicationThread都是Binder
    • Application的创建也是通过Instrumentation来完成的,这个过程和Activity对象一样,都是通过类加载器来实现的。
    • Activity的启动过程最终回到ApplicationThread中,通过ApplicationThread.scheduleLaunchActivity() 将启动Activity的消息发送并交由Handler H处理。
    • Handler H对消息的处理会调用handleLaunchActivity()->performLaunchActivity()得以最终完成Activity的创建和启动。

    源码分析Activity的工作过程

    b.Service

    • Service启动过程流程图:
    Service启动过程
    • Service绑定过程流程图:
    Service绑定过程

    结论

    • ContextImpl是Context的具体实现,通过Activity.attach()和Activity建立关联。Activity.attach()中还会完成Window的创建并和Activity&Window的关联,由此事件可传递给Window。
    • ActivityServices是一个辅助ActivityManagerService(AMS)进行Service管理的类,包括Service的启动、绑定和停止。
    • 和Activity类似的,Service的启动/绑定过程最终回到ApplicationThread中,通过ActivityThread.handleCreateService()/ActivityThread.handleBindService完成Service的启动/绑定,注意绑定Service的后续还必须 告知客户端已经成功连接Service 的这一流程,由ActivityManagerService.publishService()去完成。

    源码分析Service的工作过程

    c.ContentProvider

    • ContentProvider启动过程流程图:
    ContentProvider启动过程
    • 启动的入口为ActivityThread.main():创建ActivityThread实例并创建主线程消息队列;
    • ->ActivityThread.attach():远程调用AMS.attachApplication()并提供ApplicationThread用于和AMS的通信;
    • ->AMS.attachApplication():通过ActivityThread.bindApplication()方法和Handler H来调回ActivityThread.handleBindApplication();
    • ->ActivityThread.handleBindApplication():先创建Application、再加载ContentProvider、最后回调Application.onCreate()

    图片来源四大组件的工作过程

    • Query过程流程图:
    Query过程

    insert()delete()update()类似,这里不展开

    结论

    • ContentProvider的multiprocess属性:ContentProvider是否是单例,一般用单例。
    • 访问ContentProvider需要ContentResolver,其真正实现类是ApplicationContentResolver。当ContentProvider所在进程未启动时,第一次访问它会触发ContentProvider的创建以及进程启动。
    • 当ContentProvider所在的进程启动时,会同时被启动并被发布到AMS中。注意:ContentProvider.onCreate()Application.onCreate()执行。
    • 同样的,最终通过ActivityThread.handleBindApplication()完成ContentProvider的创建。

    源码分析 ContentProvider的工作过程

    d.BroadcastReceiver

    • 四大组件的静态注册都是在应用安装时由PackageManagerService(PMS)解析注册,当动态注册Service时流程为:
    Receiver动态注册过程
    • 广播发送和接收过程流程图:
    广播发送和接收过程

    结论:

    • 动态注册广播最终会跨进程交给AMS,并把远程Receiver( 实际上传的是IIntentReceiver,是个Binder )对象和远程IntentFilter保存起来,完成注册任务。
    • 发送广播时,系统为intent添加了两个标记位:
      • FLAG_INCLUDE_STOPPED_PACKAGES :广播也会发送到已经停止的APP(两个标记共存时,以该标记为准)
      • FLAG_EXCLUDE_STOPPED_PACKAGES :广播不会发送给已经停止的APP(系统为所有广播默认添加该标记)
    • 最终在ReceiverDispatcher .performReceive ()里回调了Receiver 的onReceive(),使得广播得以接收并处理。

    源码分析BroadcastReceiver 的工作过程


    希望这篇文章对你有帮助~

    相关文章

      网友评论

      • 小小小木虫:敏敏,四大组件源码都看过了的吗
        小小小木虫:@minmin_1123 厉害厉害的,学习一波,像插件化里面全是这些东西:smiley:
        厘米姑娘:@dn_notebook 其实没看全😅就是跟着大佬文章捋了一遍
      • huanfuan:我给你说我也学过android 还是activity的生命周期

      本文标题:要点提炼|开发艺术之四大组件

      本文链接:https://www.haomeiwen.com/subject/sigugxtx.html