ApkPlug插件化集成

2017-05-24  本文已影响0人  乐乐诶

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 

上一篇 下一篇

猜你喜欢

热点阅读