最新要闻
- 天天快资讯:免费玩没戏 《暗黑4》不会加入微软XGP:四五百块还是要花的
- 首位华裔奥斯卡影后!杨紫琼84岁母亲喜极而泣 为女儿感到自豪
- 多举措提高职教吸引力 助力职业教育“强起来”“活起来”
- 焦点简讯:曝苹果最快2024年商用MicroLED屏:比OLED更香
- 今日快讯:7月1日普及!我国将全面淘汰传统后视镜 都换汽车电子后视镜:上游供应链已准备好
- 全球今日报丨老人捡钱不愿归还 女孩崩溃下跪引网友愤怒:律师称可起诉 专家喊话不能仗着年龄大
- 环球新动态:适合买二手的硬件只有4个:学会省1000元
- 当前通讯!“自杀式”降价杀红眼:燃油车真凉透了?
- 乘客出地铁黄鹤楼站的统一姿势:集体反站拍摄绝美夜景
- 天天动态:大爷充29万做美容反悔起诉退钱:宣称能打通“任督二脉”等
- 世界聚焦:硅谷银行破产:在营销号那儿 咋又成美国赢了?
- 从大厂离职后 游戏程序员们过得咋样?
- 鲍美瑶男朋友大白_鲍美瑶
- 鼻炎患者要注意了!今年花粉高峰期来得猛又早:将持续数月
- 中消协等倡议推广小份菜、半份菜:鼓励线上点餐推出“菜量自动提醒”功能
- 焦点速读:《流浪地球2》上映51天票房破40亿 豆瓣评分又涨了!导演自曝第三部
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
每日看点!插件化开发详解
1:替换DexElements流程:
插件化原理:https://www.cnblogs.com/wnpp/p/16053088.html
(资料图片仅供参考)
插件生成apk,宿主通过反射机制和类加载器(传入插件apk),获取到插件的dexElements,并将dexElements合并到宿主的类加载器的dexElements,
这样插件所有的class都位于宿主的类加载器里面,达到宿主可以启动插件的目的。
2:启动插件普通类代码流程:
1)Plugin module:
public class Test { public int add(int a, int b){ return a + b; };}
编译生成plugin.apk,放到sdk目录下
2)Host module:
public class LoadUtil { private static final String apkpath = "/sdcard/plugin.apk"; public static void loadClass(Context context) { //反射流程 //1)获取class //2)获取class中我们需要的那个属性Filed //3)Field.get(实例化对象),得到属性对应的那个实例 //4)通过以上方法分别获取host的dexElements对象和plugin的dexElements //两层:classLoader得到pathList实例,pathList实例得到DexPathList实例 //BaseDexClassLoader->pathList->DexPathList try { // 获取DexPathList的class Class> dexPathListClass = Class.forName("dalvik.system.DexPathList"); //获取DexPathList的dexElements属性 Field dexElementField = dexPathListClass.getDeclaredField("dexElements"); //将dexElements属性设置为public dexElementField.setAccessible(true); //获取BaseDexClassLoader的class Class> classLoaderClass = Class.forName("dalvik.system.BaseDexClassLoader"); //获取pathList属性 Field pathListField = classLoaderClass.getDeclaredField("pathList"); pathListField.setAccessible(true); //获取数组的类加载器,get(实例化对象)可以获取到对象的值 //1.获取宿主的类加载器 ClassLoader pathClassLoader = context.getClassLoader(); //通过BaseClassLoader的实例化对象获取到pathList的实例化对象 Object hostPathList = pathListField.get(pathClassLoader); //通过pathList的实例得到elements的对象 Object[] hostDexElements = (Object[]) dexElementField.get(hostPathList); //2.插件 ClassLoader pluginClassLoader = new DexClassLoader(apkpath, context.getCacheDir().getAbsolutePath(), null, pathClassLoader); //通过BaseClassLoader的实例化对象获取到pathList的实例化对象 Object pluginPathList = pathListField.get(pluginClassLoader); //通过pathList的实例得到elements的对象 Object[] pluginDexElements = (Object[]) dexElementField.get(pluginPathList); //合并 //new Elements[] Object[] newElements = (Object[]) Array.newInstance(hostDexElements.getClass().getComponentType(), hostDexElements.length+pluginDexElements.length); System.arraycopy(hostDexElements, 0, newElements, 0, hostDexElements.length); System.arraycopy(pluginDexElements, 0, newElements, hostDexElements.length, pluginDexElements.length); //赋值到宿主的dexElements //hostDexElements = newElemnts dexElementField.set(hostPathList, newElements); } catch (ClassNotFoundException | IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } }}
Application启动:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); LoadUtil.loadClass(this); }}
启动插件:
try { Class> clazz = Class.forName("com.example.hotfixplugin.Test"); Method add = clazz.getMethod("add"); Object obj = add.invoke(clazz.newInstance(), 1, 2); Log.d("test", obj.toString()); } catch (ClassNotFoundException | NoSuchMethodException | java.lang.InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }3:启动插件的Activity流程:(启动插件的Activity和普通类最主要的区别是,启动Activity的时候,AMS会对Activity是否注册进行校验,而正常情况下,我们宿主是没有注册插件的Activity的)启动Activity流程:https://i.cnblogs.com/posts/edit;postId=16684049这其中关系到两次的进程间通信:1)应用调用AMS系统的服务都是实现了Binder的服务端,应用进程要想和它通信需要获取它的代理端。2)AMS到应用
在创建一个新的应用进程之后,系统首先会启动ActivityThread,ActivityThread是应用进程的主线程,在ActivityThread创建的时候会创建一个ApplicationThread的对象。这个ApplicationThread实现了一个Binder的服务端。新的进程创建完成之后通知AMS服务的之后同时把自己进程的ApplicationThread的代理端送给AMS服务。AMS服务中保存了所有应用进程的ApplicationThread的代理对象。所以AMS要想给应用进程发送消息,只需要得到目标应景进程的ApplicationThread的代理端对象即可。
滴滴插件化方案:https://github.com/didi/VirtualAPK
Activity:假设要启动插件中的Activity1,我们伪装一个Activity2骗过系统,预先注册在AndroidManifest.xml中,占个坑;
1)创建一个VasIinstruentation,通过反射机制和代理模式,替换掉系统中的Instrumentation,所有经过Instrumentation的操作都会到VasInstumentaion替代掉。
2)这时startActivity是在VasInstrumentation中执行,startActivity实际会调用到AMS中执行,因为AMS会对要启动的Activity1是否注册过进行校验。我们先保存Activity1的信息,然后告诉AMS我们要启动的是startActivity2。AMS看到启动的是Activity2,就通过校验。
3)AMS的作用:
a:对Activity的注册进行校验
b:栈的调度
c:AMS作为服务端,进行生命周期的管理,Client端的ActivityThread负责响应各个生命周期
4)AMS启动Activity2之后,根据上面流程图可知,最终会回到应用的mInstrumentation.newActivity(),newActivity通过类加载器生成实际上的Activity对象,我们的VasInstrumentation就可以对该方法进行重写,把原来实际要启动的Activity1的信息重新提取出来,替换掉当前的Activity2,生成Activity2对象,就完成了正常的Activiyt1启动。
4:查找Hook点的原则:
1)尽量静态变量或者单例对象:有利于反射和动态代理,反射的时候,如果不是静态的,就需要往前面找,直到可以得到一个类的对象为止。
2)尽量Hook public的对象和方法:谷歌提供给外面使用的,一般不会怎么修改。
关键词:
每日看点!插件化开发详解
关注:读Java性能权威指南(第2版)笔记16_垃圾回收C
全球滚动:京东小程序CI工具实践
巧妙使用SQL Server的计算列实现项目唯一规则快速定制
天天快资讯:免费玩没戏 《暗黑4》不会加入微软XGP:四五百块还是要花的
首位华裔奥斯卡影后!杨紫琼84岁母亲喜极而泣 为女儿感到自豪
世界微资讯!Redis内存碎片深入分析
多举措提高职教吸引力 助力职业教育“强起来”“活起来”
焦点简讯:曝苹果最快2024年商用MicroLED屏:比OLED更香
今日快讯:7月1日普及!我国将全面淘汰传统后视镜 都换汽车电子后视镜:上游供应链已准备好
全球今日报丨老人捡钱不愿归还 女孩崩溃下跪引网友愤怒:律师称可起诉 专家喊话不能仗着年龄大
环球新动态:适合买二手的硬件只有4个:学会省1000元
K8S-Helm
资讯:04-数据类型
环球动态:在Linux中安装containerd作为kubernetes的容器运行时
当前通讯!“自杀式”降价杀红眼:燃油车真凉透了?
乘客出地铁黄鹤楼站的统一姿势:集体反站拍摄绝美夜景
天天动态:大爷充29万做美容反悔起诉退钱:宣称能打通“任督二脉”等
世界聚焦:硅谷银行破产:在营销号那儿 咋又成美国赢了?
从大厂离职后 游戏程序员们过得咋样?
鲍美瑶男朋友大白_鲍美瑶
即时看!第129篇:JS模块化开发
每日快播:Yus框架之nl子级管控指令
鼻炎患者要注意了!今年花粉高峰期来得猛又早:将持续数月
中消协等倡议推广小份菜、半份菜:鼓励线上点餐推出“菜量自动提醒”功能
焦点速读:《流浪地球2》上映51天票房破40亿 豆瓣评分又涨了!导演自曝第三部
AMD技术岗最高头衔!DX10/11发明人、皓龙处理器之父等升任企业院士
22-23(2)第2次线上赛
【打怪升级】【rocketMq】rocket的持久化
Linux进程与线程的基本概念及区别
天天消息!k8s单节点改为高可用和更新证书
世界滚动:这还是中国乒乓球吗?王牌选手接连倒下,对手赢球后开心改签机票
欧盟约法三章:苹果无法对iPhone 15 USB-C加密来限制充电速度
每日快报!董明珠称很烦吹捧她的员工:不敢讲真话 没法信任
环球滚动:高尔夫球“名场面”或消失!剧版《最后生还者2》将修改原作剧情
马来西亚原装进口:猫山王榴莲雪糕4.9元/支四折发车
焦点讯息:联想YOGA Pro系列升级:新机全系标配32GB内存+1TB存储
环球今亮点!清华博士回应送外卖:不是炒作 曾创业欠下了百万元债务
环球今热点:299元 雷神X3电竞路由器上架:512MB内存 可253台设备同时连
即时看!比亚迪又拿大单:英国公司订购5000辆元Plus EV 价格比国内贵了一倍
全球热点!最强消费级PCIe 5.0 SSD有多强!技嘉大雕510K 2TB评测:顺序读写破10GB/s、4K超100MB/s
全球速讯:使用symbolicatecrash工具符号化Crash日志
环球速看:开心档之HTML 属性
全球热门:博雅互动(00434.HK)将于3月23日举行董事会会议以审批全年业绩
世界消息!官方:着力解决自媒体内容失真问题、清除违规吸粉
董明珠称批评人很快乐:帮助对方成长
不受支持的PC强行升级Win11 烦人的水印又回来了 微软回应
快看:PPT既视感!电视剧《狂飙》更换新片头:曾被指抄袭网飞纪录片
天天最资讯丨哈佛大学研究:体力劳动更多的男性生育能力更强
当前热点-网站https 问题记录
出道即封神的ChatGPT,现在怎么样了?
IntelliJ IDEA使用教程——不使用maven管理下导入jar包
每日精选:使用Docker搭建MinIO集群服务
CommonsBeanUtils1反序列化分析
全球快资讯:董明珠:如果员工经常在我面前拍马屁 我就开除他
当前关注:网店因商品拆封拒绝七天无理由退货:最终被罚4万元
焦点!全村停电 男子用比亚迪DM-i给自家全屋供电 邻居:为啥就他家有电?
丫丫伙食新添胡萝卜:但它没碰
天天快讯:剧版《最后生还者》顺利收官:M站评分达84分
CommonsCollections4反序列化分析
环球视讯!前端开发爬虫首选puppeteer
聚焦:subtotal函数的作用_SUBTOTAL函数的用法
环球观天下!中国移动涨停 市值2.1万亿创历史新高 挑战A股第一贵州茅台
今日聚焦!亲肤0刺激 润本婴儿驱蚊喷雾大瓶9.9(超市39.9)
天天视讯!高蛋白低脂美味!舌里减脂鸡胸肉5袋到手12.9元
头条焦点:净利润翻倍 宁德时代在补什么课?
最新资讯:卖事故车被判退一赔三!车主:特斯拉让我赔代步车50万租金
环球消息!【数字化运营】PagerDuty平台与上海道宁帮助您的数字基础设施中自动化、编排和加速响应
LocalDateTime应用比较日期
玩家不用担心 分析师称微软收购动视暴雪只会伤害索尼
全球观焦点:游客吐槽25元看海洋馆就几个鱼缸:现场和家里客厅一样大
环球百事通!樱桃推出KW 9200 MINI超薄键盘:剪刀脚按键、三模连接
全球快资讯丨雅阁车主第一次坐比亚迪汉 自侃像是土包子进城 信仰崩塌
焦点讯息:美国公示丫丫回国相关申请:快回家了!
全球观速讯丨二进制安全——缓冲区溢出
每日看点!数组指针&一维数组&二维数组ve
【环球时快讯】面试官:如何在千万级数据中查询 10W 的数据,都有什么方案?
网络安全(中职组)-B模块:压缩包破解
全球快资讯:Rancher 管理 Kubernetes 集群
李想:L7、L8、L9是世界上最安全的车 副驾坐的是我老婆
天天快报!美版《西游记》定档!阵容强大:奥斯卡影后杨紫琼饰观音、吴彦祖演美猴王
日本原装进口!雀巢金牌速溶黑咖啡大促 28.9元到手
Android 14不再允许“杀后台”!一键加速App别装了
上汽投资成立股权投资合伙企业 出资额5亿
环球快资讯丨解惑:教你在 Arch Linux 终端上更改 WiFi 密码
教程|在矩池云使用 Stable Diffusion web UI v1.5 模型和 ControlNet 插件
【环球新要闻】应聘软件测试 HR 会问到哪些问题?收藏这一篇就够了!
Nebius Welcome Round (Div. 1 + Div. 2)
环球快讯:火山引擎 DataTester:一个 A/B 测试,将一款游戏的核心收益提升了 8%
环球最资讯丨华擎Intel显卡集体降价 最多20%:RTX 3060瞬间不香了
容声冰箱质量怎么样?容声冰箱怎么调温?
oracle是什么软件?oracle怎么创建表空间?
bios是什么意思?如何刷主板bios?
苹果手表可以连接安卓手机吗?苹果手表怎么配对新的手机?
empty来显示暂无数据简直太好用,阻止用户复制文本user-select
raw格式怎么打开?raw格式怎么转换jpg?
【快播报】《瞬息全宇宙》七项大奖横扫奥斯卡!杨紫琼获封奥斯卡影后:亚洲首位
新一代Y9000P来了!联想拯救者2023生态新品发布会官宣
环球短讯!小红书后台删用户照片遭系统拦截?官方回应:只是清理临时缓存
仅隔17天 中国火箭又一次成功为海外客户发射荷鲁斯2号卫星