ApkPlug插件化集成

1.准备工作

        登录ApkPlug官网注册账号console.apkplug.com/ ,开通相关业务。

        选择插件托管——>应用列表——>创建新应用(即主程序、宿主应用)。

        

创建插件   

         然后进入应用详情,创建容器。容器即为保存一个或多个插件的集合。

         再到插件列表中创建一个插件,将插件与应用绑定。


创建插件

2.主应用开发

2.1宿主配置

  a、下载jar包及so文件 github.com/apkplug/apkplug_jar/3.8.0 

        导入BundleCloud(x.x.x)-Release.jar并在jni/armeabi下加入libApkPlugPatchLibrary.so (其他架构自行添加,各种so已经提供)

        *注:如果出现加载64位或32位so文件出错,请根据需求只保留32或64中一种so文件

        github.com/apkplug/apkplug_jar/v_old 下为老版本apkplug兼容版,不便升级可以先使用此包

  b、主应用权限配置

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE" />

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

android 6.0需要自己动态申请如下权限,不申请可能有不可预测的错误:

Manifest.permission.WRITE_EXTERNAL_STORAGE

Manifest.permission.READ_EXTERNAL_STORAGE

Manifest.permission.READ_PHONE_STATE

Manifest.permission.ACCESS_NETWORK_STATE

   c、主应用清单文件配置

<meta-data android:name="apkplug_appid" android:value="your appid" />

<meta-data android:name="apkplug_containerid" android:value="your containerid"/>

<activity android:name="org.apkplug.app.apkplugActivity"

  android:theme="@android:style/Theme.Translucent.NoTitleBar"

  android:configChanges="orientation|keyboardHidden"/>

<intent-filter>

<action android:name="android.intent.action.MAIN"></action>

</activity>

<service android:name="com.apkplug.libmerge.common.MergeServeice" android:process=":merge" />

<service android:name="org.apkplug.app.apkplugService" />

<provider android:name="org.apkplug.app.apkplugProvider" android:authorities="xxx.apkplugprovider" />


xxx为宿主应用包名,不能用'.'代替

apkplug_appid应用详情查询,apkplug_containerid容器详情查询。

    d、代码混淆

-keep class com.apkplug.** { *;}

-keep class org.apkplug.** { *;}

-keep class org.osgi.** { *;}

-keep class extends org.osgi.**

-keep class tengxin.sv.** { *;}

2.2主应用框架启动

主应用启动Apkplug最简只需要一段代码即可,建议在Application中启动框架。

FrameworkInstance frame=FrameworkFactory.getInstance().start(List,Context);

得到System插件上下文BundleContext

BundleContext bundleContext = FrameworkFactory.getInstance().getFrame().getSystemBundleContext();

BundleContext 可以用于宿主管理插件,与插件通信等

2.3初始化

插件托管能帮你使用后台上传的插件,所有功能在PlugManager统一获取,PlugManager获取方法:

PlugManager.getInstance()

在使用任何插件托管相关接口之前,需要提前调用init方法

PlugManager.getInstance().init(Context context,BundleContext bundleContext,String publickey,boolean isDebug)

参数说明:

publickey为后台为应用生成的key,到后台应用详情里可以找到。

isDebug: 是否debug模式,true:后台数据实时响应  false:后台数据1分钟后更新,1分钟内请求为缓存信息

如果是android 6.0系统,还需要调用requestPermission

PlugManager.getInstance().requestPermission(Activity activity)

来申请权限,并在onRequestPermissionsResult中调用回调来处理请求权限结果。

PlugManager.getInstance().onRequestPermissionsResult(int requestId, Activity activity,String[] permissions, int[] grantResults)

2.4注销SDK

当不再使用功能后,调用onDestroy,注销上下文

@Override

protected void onDestroy() {

       super.onDestroy();

      plugManager.onDestroy();

}

3.插件的管理

3.1SystemBundle

apkplug初始化以后默认有一个系统插件叫SystemBundle,它永远在插件列表的第一个位置,利用该插件您可以实现管理插件,与插件通信等功能

获取系统插件上下文

BundleContext bundleContext = FrameworkFactory.getInstance().getFrame().getSystemBundleContext();

3.2使用短连接管理插件

在插件详情中,我们自动为您生成短链,可以直接拷贝用于安装插件


插件短连接与ID

使用短链安装的插件,必须在插件的plugin.xml中配置Short-Links=“短链”,否则查询不到

PlugManager manager = PlugManager.getInstance();

Bundle bundle = manager.checkLocalShortLinkPlug("http://xxxx");

if(bundle != null){

      System.out.println("找到了插件");

      }else{

      System.out.println("插件没找到");

      }

3.3使用短链接安装插件

此接口会先查找本地是否已经安装了这个短链指向的插件,如果已经安装则不管有没有更新版的插件都不会再次下载安装。如果没有安装,则下载安装。

PlugManager.getInstance().installPlugFromShortLink("http://yyfr.net/q0Y", new OnInstallSLPlugListener() {

@Override

public void onDownloadProgress(String s, String s1, long l, long l1) {

      System.out.println("正在下载 百分比:"+l/l1);

      }

@Override

public void onInstallSuccess(org.osgi.framework.Bundle bundle) {

      System.out.println("安装成功了");

      }

@Override

public void onInstallFailuer(int i, String s) {

      System.out.println("安装失败了");

      }

@Override

public void onDownloadFailure(String s) {

      System.out.println("下载失败了");

      }

});

3.4使用短链接更新插件

此接口会先检查本地是否已经安装此短链指向的插件,如果没安装则直接下载当前最新版安装。如果安装了,则先检测已安装插件的版本,如果不是最新的则下载最新的覆盖安装。如果检测本地已经是最新版本则不做处理。

注意在短链插件开发时在plugin.xml中配置Short-Links=“短链”,否则即使已经安装也找不到这个插件

PlugManager.getInstance().updatePlugByShortLink("http://yyfr.net/q0Y", new OnUpdateSLListener() {                                                                              

.......

3.5安装插件

apkplug支持两种安装方式:   1.安装云端托管的插件     2.安装Assets目录下的插件

a.安装云端托管插件.此接口可以根据从云端获取的PlugInfo把对应的插件安装到本地

安装云端插件接口为:

PlugManager.getInstance().installPlug(Context context, PlugInfo plugInfo, OnInstallListener listener);

或者

PlugManager.getInstance().installPlug(Context context, PlugInfo plugInfo,  InstallProperties properties,OnInstallListener listener);

b.安装本地Assets目录下的插件

安装本地插件接口为:

PlugManager.getInstance().installAssets(Context context,String apkName,String version,OnInstallListener listener);

或者

PlugManager.getInstance().installAssets(Context context,String apkName,String plugVersion,InstallProperties properties, final OnInstallListener listener);

后者可以通过InstallProperties 传入一些安装检测条件,其他相同'

apkName:assets下插件apk的文件名

plugVersion:assets下插件apk的版本号

4.插件开发

4.1插件相关配置

osgi包导入:下载地址github.com/apkplug/apkplug_jar/tree/master/OSGI.jar 下载最新版本即可

拷贝osgi.jar到项目的libs目录下在module的build.gradle中加入以下代码片段

dependencies {

      provided files('libs/osgi.jar')

}

4.2配置文件plugin.xml

plugin.xml 与AndroidManifest.xml功能相似提供插件的系统属性。

将plugin.xml放在插件的assets目录下即可

一  plugin.xml有以下几个属性比较重要

1 plug_id            --插件id,用于标识这个插件,在后台插件详情获取

2 Short-Links        --使用短链操作插件的话,必须将短链配置到此项

3.Bundle-Name          --插件名称

4.Bundle-SymbolicName  --插件唯一标识类似安卓程序应用标识

5.Bundle-Version      --插件版本号 如100

6.Bundle-Activator    --插件入口类 ,通过它框架可在启动插件的时候找到并调用start()函数

7.Bundle-Activity      --插件的 Lanucher Activity路径(多个包以 ‘,‘ 分割)

8.Export-Package      --提供给其他插件使用的java类需要导出对应包路径(多个包以 ‘,‘ 分割)

9.Import-Package      --插件内部没有这样的java类需要从其他插件导入(多个包以 ‘,‘ 分开)

10.Bundle-Service      --插件的Service类路径  (多个包以 ‘,‘ 分割)  【v2.0.0新增】

11.Bundle-Receiver      --插件接收系统广播类路径  (多个包以 ‘,‘ 分割)  【v2.0.0新增】

示例: console.apkplug.com/documents/plug/prepare/configure/sample

4.3插件入口类BundleActivator

BundleActivator就两个函数

public void start(BundleContext context)  插件启动时被调用

public void stop(BundleContext context)  插件停止时被调用

我们可以在start函数中获取插件上下文BundleContext 并且初始化或注册一些插件提供的OSGI服务

我们可以在stop函数中注销OSGI服务,释放插件开辟的相关内存等。

示例:console.apkplug.com/documents/plug/prepare/BundleActivator/sample

4.4其他关于插件的

附录:console.apkplug.com/documents/plug/appendix/Bundle

5.宿主和插件的通信

官方文档共提供了三种,目前只简单介绍推荐的第一种RPC通信.

bundlerpc支持的功能:

1. 支持代码注册和静态注册两种方式

2. 插件间通信需要提前约定接口(interface)但:

     2.1 插件与宿主可以同时存在约定的接口

     2.2 同时bundlerpc提供一套通用的回调接口,尽量简化约定接口数

     2.3 bundlerpc提供一个可序列化java对象池ObjectPool

          2.3.1 利用ObjectPool可以将任意对象通过Intent和其他序列化方式传输

          2.3.2.该功能对应的是Dispatch延时回复功能

3. 支持URL方式查询服务

示例代码:console.apkplug.com/documents/Dispatch/bundlerpc 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,778评论 6 342
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 介绍自己负责的部分,如何实现的。 自定义view viewGroup activity的启动流程 事件传递及滑动冲...
    东经315度阅读 1,199评论 1 4
  • 场景 单机应用已经越来越不能符合目前越来越复杂的产品需求了。即使是小型应用,至少也需要部署2台以上的服务器做集群。...
    IvanEye阅读 3,598评论 3 11