面试:插件化相关---service

news2024/11/28 15:57:38

插件service启动分析

同样的,先来看看service的常规启动流程

  • 调用contextimpl.startService/bindService/stopService -> AMS,AMS对应创建ServiceRecord和token后,通知ActivityThread
  • ActivityThread收到startService后,会创建service并保存到mService的ArrayMap,key为token,接着调用oncreate
  • ActivityThread接着收到handleServiceArgs, 根据token拿到service,接着调用onStartCommond并传入intent
  • ActivityThread收到bindservice后,从根据token拿到service,接着调用onBind拿到native binder,接着调用publishService将native binder传到AMS

Service跟Activity还是存在很大的区别的,service非常独立,也就是说,系统创建service后,除了调用规定的那些回调,传递intent外,剩下就是service自己玩自己的,跟系统一毛钱关系都没有了。

Service无法拥有多实例

Service组件与Activity组件另外一个不同点在于,对同一个Service调用多次startService并不会启动多个Service实例,而非特定Flag的Activity是可以允许这种情况存在的,因此如果用StubService的方式,为了实现Service的这种特性,必须建立一个StubService到插件Service的一个Map,Map的这种一一对应关系使得我们使用一个StubService对应多个插件Service的计划成为天方夜谭。

至此,结论已经非常清晰——对于Service组件的插件化,我们不能简单地套用Activity的方案。

对于DroidPlugin来说,插件service的hook,则会简单很多,只需要用一个stub service做为代理,在stubservice内部根据传入的intent去管理插件service对象即可

在startservice和bindservice时,只需要把目标sevice缓存stubservice,并将真实的intent作为extra传递到stub service就可以了

通过反射调用ActivityThrea的方法创建service,从而达到调用oncreate的目地

如何实现Service的插件化?

上文指出,我们不能套用Activity的方案实现Service组件的插件化,可以通过手动控制Service组件的生命周期实现;我们先来看一下Service的生命周期:

从图中可以看出,Service的生命周期相当简单:整个生命周期从调用 onCreate() 开始起,到 onDestroy() 返回时结束。对于非绑定服务,就是从startService调用到stopService或者stopSelf调用。对于绑定服务,就是bindService调用到unbindService调用;

如果要手动控制Service组件的生命周期,我们只需要模拟出这个过程即可;而实现这一点并不复杂:

  1. 如果以startService方式启动插件Service,直接回调要启动的Service对象的onStartCommand方法即可;如果用stopService或者stopSelf的方式停止Service,只需要回调对应的Service组件的onDestroy方法。
  2. 如果用bindService方式绑定插件Service,可以调用对应Service对应的onBind方法,获取onBind方法返回的Binder对象,然后通过ServiceConnection对象进行回调统计;unBindService的实现同理。

完全手动控制

现在我们已经有了实现思路,那么具体如何实现呢?

我们必须在startService,stopService等方法被调用的时候拿到控制权,才能手动去控制Service的生命周期;要达到这一目的非常简单——Hook ActivityManagerNative即可。在Activity的插件化方案中我们就通过这种方式接管了startActivity调用,相信读者并不陌生。

我们Hook掉ActivityManagerNative之后,可以拦截对于startService以及stopService等方法的调用;拦截之后,我们可以直接对插件Service进行操作:

  1. 拦截到startService之后,如果Service还没有创建就直接创建Service对象(可能需要加载插件),然后调用这个Service的onCreate,onStartCommond方法;如果Service已经创建,获取到原来创建的Service对象并执行其onStartCommand方法。
  2. 拦截到stopService之后,获取到对应的Service对象,直接调用这个Service的onDestroy方法。

这种方案简直简单得让人不敢相信!很可惜,这么干是不行的。

首先,Service存在的意义在于它作为一个后台任务,拥有相对较高运行时优先级;除非在内存及其不足威胁到前台Activity的时候,这个组件才会被系统杀死。上述这种实现完全把Service当作一个普通的Java对象使用了,因此并没有完全实现Service所具备的能力。

其次,Activity以及Service等组件是可以指定进程的,而让Service运行在某个特定进程的情况非常常见——所谓的远程Service;用上述这种办法压根儿没有办法让某个Service对象运行在一个别的进程。Android系统给开发者控制进程的机会太少了,要么在AndroidManifest.xml中通过process属性指定,要么借助Java的Runtime类或者native的fork;这几种方式都无法让我们以一种简单的方式配合上述方案达到目的。

代理分发技术

既然我们希望插件的Service具有一定的运行时优先级,那么一个货真价实的Service组件是必不可少的——只有这种被系统认可的真正的Service组件才具有所谓的运行时优先级。

因此,我们可以注册一个真正的Service组件ProxyService,让这个Service承载一个真正的Service组件所具备的能力(进程优先级等);当启动插件的服务比如PluginService的时候,我们统一启动这个ProxyService,当这个ProxyService运行起来之后,再在它的onStartCommand等方法里面进行分发,执行PluginService的onStartCommond等对应的方法;我们把这种方案形象地称为「代理分发技术」

代理分发技术也可以完美解决插件Service可以运行在不同的进程的问题——我们可以在AndroidManifest.xml中注册多个ProxyService,指定它们的process属性,让它们运行在不同的进程;当启动的插件Service希望运行在一个新的进程时,我们可以选择某一个合适的ProxyService进行分发。也许有童鞋会说,那得注册多少个ProxyService才能满足需求啊?理论上确实存在这问题,但事实上,一个App使用超过10个进程的几乎没有;因此这种方案是可行的。

Android 插件化原理解析——Service的插件化 - 腾讯云开发者社区-腾讯云

插件化-插件Service的运行管理 - 简书

如何评价360的Android插件化框架RePlugin? - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49455.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

少儿编程 电子学会图形化编程等级考试Scratch一级真题解析(选择题)2022年9月

2022年9月scratch一级真题解析 选择题(共25题,每题2分,共50分) 1、点击绿旗,下列哪个选项可以实现播放马叫声并在声音全部播放完后,马向右移动 A、 B、 C、 D、

[附源码]计算机毕业设计JAVA小说网站的设计与实现1

[附源码]计算机毕业设计JAVA小说网站的设计与实现1 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM m…

基于RV1126 Video分析-----链接 isp 与mipi csi 的media模块

从前文&#xff1a;<<图像处理模块所代表的V4L2设备注册>> 中了解到。rkcif_mipi设备注册的过程就是以设备通知器为线索&#xff0c;从顶向下&#xff0c;依次找到下一级设备&#xff0c;添加到V4L2设备种&#xff0c;循环处理。将全部的子设备整理到 V4L2设备中&a…

《InnoDB引擎五》Checkpoint技术

Checkpoint技术 缓冲池的设计目的是为了协调CPU速度与磁盘速度的鸿沟。因此页的操作首先都是在缓冲池中完成的。如果一条DML语句&#xff0c;比如Update或Delete改变了页中的记录&#xff0c;那么此时页是脏的&#xff0c;即缓冲池中的页要比磁盘的新&#xff0c;那么数据库就需…

网络编程简单学习

目录 一、 概述 1. 什么是计算机网络&#xff1f; 2. 网络编程的目的 3. 需要达到什么样的效果&#xff1f; 二、 网络通信的两个要素 1. 通信双方地址 2. 规则&#xff1a;网络通信协议 三、IP地址 1. IP地址概述 2. IP地址分类 3. 域名 四、端口 五、通信协议 …

Python破解WIFI密码完整源代码,实测可成功破解

目录 # 修正记录&#xff1a;2022-12-01 1&#xff0c;先安装Python环境(这个不用多说了吧) 2&#xff0c;安装PyWifi 3,自己手工整理高频弱口令&#xff0c;不建议程序生成的字典&#xff0c;生成的字典成功率实在太低。 4&#xff0c;自己生成字典的算法&#xff1a; 5…

九联UNT413A_S905L3A__AI语音_默认打开ADB_完美线刷固件包【可救砖】

UNT413A_S905L3A__AI语音_默认打开ADB_完美线刷固件包【可救砖】_基于云南原机制作_端口5555 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;…

PyQt5 设置窗口背景

PyQt5 设置窗口背景使用setStyleSheet设置窗口背景图片使用setStyleSheet设置窗口背景颜色使用QPalette设置窗口背景颜色使用QPalette设置窗口背景图片使用paintEvent设置窗口背景颜色使用paintEvent设置窗口背景图片窗口背景主要包括&#xff1a;背景色和背景图片。设置窗口背…

跨境电商必知的交叉销售和追加销售:2022终极指南

关键词&#xff1a;跨境电商、交叉销售、追加销售 跨境电商可以从客户那里获得的潜在收入不会在销售点结束。 交叉销售和追加销售通过吸引客户增加支出来增加您的收入。这是一个双赢的局面&#xff0c;消费者获得了卓越的体验&#xff0c;而你赚到了更多的钱。 但是&#xff0c…

【Pandas数据处理100例】(九十七):Pandas中的eval()函数使用方法

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

axure到底好不好学,有哪些技巧

Axure学习难吗&#xff1f;这个问题一直引起很多朋友的讨论&#xff0c;有的觉得难&#xff0c;有的觉得不难。当然&#xff0c;人不一样&#xff0c;每个人的学习方式也不一样&#xff0c;对学习难度的理解自然也不一样&#xff0c;这个问题自然没有定论。 ​在学习的时候&…

数据库------E-R图和关系模型

1、请输出下面E-R图,并转换成关系模型 有实体 A B C A属性有a1(主键),a2,a3 B属性有b1(主键),b2,b3 C属性有c1(主键),c2,c3 A和B之间有X关系,B和C之间有Y关系,A和C之间有Z关系 一个A对应多个B,一个B对应多个A 一个A对应一个C,一个C对应一个A 一个B对应一个C,一个C对应多…

Js逆向教程19-websocket介绍

Js逆向教程19-websocket介绍 作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 一、websocket介绍 Ws和Wss的区别相当于http和https的区别&#xff0c; 如果你想写一个聊天页面&#x…

Android Studio实现课程表应用,美观又实用(Kotlin版本)

项目目录一、应用概述二、主要技术三、开发环境四、主要功能1、设置课程表2、导入导出3、上下课提醒五、运行演示一、应用概述 本次课程表应用功能非常丰富&#xff0c;而且非常实用&#xff0c;可以添加学期的课程信息&#xff0c;设置展示的课程页面&#xff0c;设置上下课时…

李沐《动手学深度学习》第二版 pytorch笔记1 环境搭建

李沐《动手学深度学习》第二版pytorch笔记1 搭建环境 文章目录李沐《动手学深度学习》第二版pytorch笔记1 搭建环境此时尚有耐心虚拟环境搭建创建虚拟环境查看已有的虚拟环境激活虚拟环境安装深度学习框架和d2l软件包安装d2l安装pytorch连接到虚拟环境测试一下再试试...好难搞下…

[附源码]Python计算机毕业设计Django的剧本杀管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

《Mission Red in Slience》——这本“连环画”值得一看

生命离不开血液。 血液对人的意义是不言而喻的&#xff0c;当失血到总量的30%时&#xff0c;人就会有生命危险。这也就意味着献血有时是看似渺小&#xff0c;实际拯救生命的壮举。同时适度的献血对献血人也有助的。 但很多人对献血缺乏认识&#xff0c;认为其可能具有危险性&…

[附源码]Python计算机毕业设计SSM乐跑(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

3.每天进步一点点-Python爬虫需要了解HTTP 请求报文

14天学习训练营导师课程&#xff1a; 杨鑫《Python 自学编程基础》 杨鑫《 Python 网络爬虫基础》 杨鑫《 Scrapy 爬虫框架实战和项目管理》 文章目录1.HTTP 请求报文1.1 请求行1.2 请求头1.3 空行1.4 请求正文1.HTTP 请求报文 ​ HTTP&#xff08;Hyper Text Transfer Protoc…

基于51单片机锂电池电压电量检测(原理图+PCB+程序)

资料编号&#xff1a;198 下面是该资料仿真演示视频&#xff1a; 198-基于51单片机锂电池电压电量检测&#xff08;原理图PCB程序全套资料&#xff09;功能介绍&#xff1a; 采用51系列自带AD的单片机stc12c5a60s2型号单片机&#xff08;也是51单片机&#xff0c;外观引脚大小…