Android 插件化开发(四):插件化实现方案
在经过上面铺垫后,我们可以尝试整体实现一下插件化了。这里我们先介绍一下最简单的实现插件化的方案。
一、最简单的插件化实现方案
最简单的插件化实现方案,对四大组件都是适用的,技术面涉及如下:
1). 合并所有插件的Dex,来解决插件的类的加载问题。
2). 预先在宿主的AndroidManifest.xml文件中声明插件的四大组件。(如果插件组件过多会很麻烦)
3). 把插件中的所有资源一次性的合并到宿主的资源中。(合并时可能会导致id冲突)
使用此组件化方案实现时,Service、ContentProvider 和 Receiver 只要合并 dex 就够了,因为这些没有资源访问的概念。
但是Activity插件化实现时就会比较麻烦,因为Activity严重依赖资源,想实现Activity的插件化就必须解决加载插件中资源的问题。
在 Android 插件化开发(三):资源插件化 中我们介绍过AssetsManager和Resource这两个类的关系,AssetManager有一个addAssetPath方法,可以一次性把插件的路径都导入,然后再生成一个含有全局资源的Resource,以后无论查找插件还是宿主的的资源都能找到了。
虽然此方案能实现插件化,但是此方案有很大的问题:
1. 插件的四大组件要事先声明,无法动态新增,这样对于Activity来说是无法兼容的问题(其他组件相对问题较少)。
2. 资源id会冲突。
3. 无法预料插件内Activity,对于插件内动态新增的Activity无法进行使用。
项目代码仓库地址:https://github.com/renhui/RHPluginProgramming/tree/master/ZeusStudy
了解如何实现一个最简单的插件化之后,我们再整理一下Activity如何实现插件化。这里单独再提一下 Activity 是因为 Activity 是 App 中使用频率最高的组件,所以这里我们先讲述一下Activity的插件化。
Activity 的插件化需要解决3方面的技术问题:
1). 宿主App可以加载App中的类。
2). 宿主App可以加载App中的资源。
3). 宿主App可以加载插件中的Activity。
前两个技术问题,我们已解决了,这里我们讲一下第3个的技术问题的解决方案。主要的解决方案有很多种,这里只简单以两个有标志性的框架:
a. 以DroidPlugin框架为代表的动态替换方案,提供对Android底层的各类进行Hook,以达到插件化中的四大组件的目的。
b. 以DynamicLoadApk框架为代表的静态代理方案,通过ProxyActivity统一加载插件中的所有Activity。
下面我们再讲一下DynamicLoadApk框架,此框架在《Android插件化开发指南》书中重点提及了,本人也比较感兴趣。
三、DynamicLoadApk 插件化框架
DynamicLoadApk 是一个开源的 Android 插件化框架。
插件化的优点包括:(1) 模块解耦,(2) 动态升级,(3) 高效并行开发(编译速度更快) (4) 按需加载,内存占用更低等等。
DynamicLoadApk 提供了 3 种开发方式,让开发者在无需理解其工作原理的情况下快速的集成插件化功能。
- 宿主程序与插件完全独立;
- 宿主程序开放部分接口供插件与之通信;
- 宿主程序耦合插件的部分业务逻辑。
1. DynamicLoadApk 框架核心概念
(1) 宿主:主 App,可以加载插件,也称 Host。
(2) 插件:插件 App,被宿主加载的 App,也称 Plugin,可以是跟普通 App 一样的 Apk 文件。
(3) 组件:指 Android 中的Activity、Service、BroadcastReceiver、ContentProvider,目前 DL 支持Activity、Service以及动态的BroadcastReceiver。
(4) 插件组件:插件中的组件。
(5) 代理组件:在宿主的 Manifest 中注册,启动插件组件时首先被启动的组件。目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。
(6) Base 组件:插件组件的基类,目前包括 DLBasePluginActivity(插件 Activity 的基类)、DLBasePluginFragmentActivity(插件 FragmentActivity 的基类)、DLBasePluginService(插件 Service 的基类)。
DynamicLoadApk 原理的核心思想可以总结为两个字:代理。通过在 Manifest 中注册代理组件,当启动插件组件时首先启动一个代理组件,然后通过这个代理组件来构建、启动插件组件。
2. DynamicLoadApk 框架设计思路
上面是 DynamicLoadApk 的总体设计图,DynamicLoadApk 主要分为四大模块:
(1) DLPluginManager
插件管理模块,负责插件的加载、管理以及启动插件组件。
(2) Proxy
代理组件模块,目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。
(3) Proxy Impl
代理组件公用逻辑模块,与(2)中的 Proxy 不同的是,这部分并不是一个组件,而是负责构建、加载插件组件的管理器。这些 Proxy Impl 通过反射得到插件组件,然后将插件与 Proxy 组件建立关联,最后调用插件组件的 onCreate 函数进行启动。
(4) Base Plugin
插件组件的基类模块,目前包括 DLBasePluginActivity(插件 Activity 的基类)、DLBasePluginFragmentActivity(插件 FragmentActivity 的基类)、DLBasePluginService(插件 Service 的基类)。
3. DynamicLoadApk 流程说明
上面是调用插件 Activity 的流程图,其他组件调用流程类似。
(1) 首先通过 DLPluginManager 的 loadApk 函数加载插件,这步每个插件只需调用一次。
(2) 通过 DLPluginManager 的 startPluginActivity 函数启动代理 Activity。
(3) 代理 Activity 启动过程中构建、启动插件 Activity。
四、其他的插件化解决方案
在介绍其他的插件化解决方案之前,我们先看一下插件化技术的演进图:
以下是相关的项目地址:
1) 携程:https://github.com/CtripMobile/DynamicAPK
2) 奇虎:https://github.com/Qihoo360/DroidPlugin
3) 任玉刚: https://github.com/singwhatiwanna/dynamic-load-apk
4) Dynamic Loader:https://github.com/mmin18/AndroidDynamicLoader
7) Small:https://github.com/wequick/Small
虽然插件化的相关框架不少,但是核心技术还是不变的,那就是:反射 + 代理。
Android 插件化开发(四):插件化实现方案的更多相关文章
- 从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装
标题:从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11260750. ...
- 从零开始实现ASP.NET Core MVC的插件式开发(五) - 插件的删除和升级
标题:从零开始实现ASP.NET Core MVC的插件式开发(五) - 使用AssemblyLoadContext实现插件的升级和删除 作者:Lamond Lu 地址:https://www.cnb ...
- Android 音视频开发(四):使用 Camera API 采集视频数据
本文主要将的是:使用 Camera API 采集视频数据并保存到文件,分别使用 SurfaceView.TextureView 来预览 Camera 数据,取到 NV21 的数据回调. 注: 需要权限 ...
- 从零开始实现ASP.NET Core MVC的插件式开发(八) - Razor视图相关问题及解决方案
标题:从零开始实现ASP.NET Core MVC的插件式开发(八) - Razor视图相关问题及解决方案 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun ...
- 从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用
标题:从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用. 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/1171 ...
- 从零开始实现ASP.NET Core MVC的插件式开发(七) - 近期问题汇总及部分解决方案
标题:从零开始实现ASP.NET Core MVC的插件式开发(七) - 问题汇总及部分解决方案 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/12 ...
- 从零开始实现ASP.NET Core MVC的插件式开发(九) - 升级.NET 5及启用预编译视图
标题:从零开始实现ASP.NET Core MVC的插件式开发(九) - 如何启用预编译视图 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/1399 ...
- Android组件化和插件化开发
http://www.cnblogs.com/android-blogs/p/5703355.html 什么是组件化和插件化? 组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Modul ...
- 插件化开发—动态加载技术加载已安装和未安装的apk
首先引入一个概念,动态加载技术是什么?为什么要引入动态加载?它有什么好处呢?首先要明白这几个问题,我们先从 应用程序入手,大家都知道在Android App中,一个应用程序dex文件的方法数最大不能超 ...
- 插件化开发—动态载入技术载入已安装和未安装的apk
首先引入一个概念,动态载入技术是什么?为什么要引入动态载入?它有什么优点呢?首先要明确这几个问题.我们先从 应用程序入手,大家都知道在Android App中.一个应用程序dex文件的方法数最大不能超 ...
随机推荐
- 和SharpDX坑爹的Variant刚正面
和SharpDX坑爹的Variant刚正面 几个月前我写了和篇文章<.NET中生成动态验证码>文章,其实里面藏着一个大坑.运行里面的代码,会发现运行的gif图片并没有循环播放: 细心的网友 ...
- java Math类常用方法
package com.niuke.test; public class MathDemo { public static void main(String args[]){ /** * abs求绝对 ...
- Nginx 配置整理
链接:nginx配置详细解析 1. C10k问题:无法同时并发超过(1w)客户端请求而出现的问题. nginx默认配置超过1w并发: 2.配置文件conf/nginx.conf (1)user www ...
- 从入门到入土:Lambda完整学习指南,包教包会!
什么是Lambda表达式 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口.lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使 ...
- tomcat部署项目,详细!
一.导出war包 1.先导出项目的war包(idea为例) 点+号,选择 之后点ok,确定,关闭窗口,回到idea主页面 在弹出窗口中选择新建的war,选build 之后在war导出目录,找到这个wa ...
- mysql主从架构搭建
1.配置文件,开启二进制日志 vim /etc/my.cnf 在mysql下增加如下内容 server-id= log-bin=mysql-bin relay-log=mysql-relay 2.登录 ...
- 学习AI之NLP后对预训练语言模型——心得体会总结
一.学习NLP背景介绍: 从2019年4月份开始跟着华为云ModelArts实战营同学们一起进行了6期关于图像深度学习的学习,初步了解了关于图像标注.图像分类.物体检测,图像都目标物体检测等 ...
- 关于maven-assembly-plugin插件打包,有部分无法打包的情况解决方法
今天在使用maven-assembly-plugin 对生产者进行打包,然后在linux中发布时.将包打包之后,发现mybtis的xml无法识别,然后查看原因说是没有这个包,我当时就纳闷了,都是基操( ...
- Spring事物实例
Spring事务实例: entity实体类: public class Accounts { private int accountid; private String accountname; pr ...
- PG数计算
PG数计算 原地址:http://xiaqunfeng.cc/2017/09/15/too-many-PGs-per-OSD/ ceph告警问题:”too many PGs per OSD” 的解决方 ...