apkplug 插件怎么使用sam12宿主机架vst插件的jar包了

android插件化-apkplug从宿主启动插件Activity-06
插件是一个apk文件它存在自己的Activity界面和UI显示,本节将讲解如何配置插件的启动Activity以及怎样从宿主启动它。
一 配置插件apk的对外启动Activity (内部activity不需要配置)
与普通app不同,插件Manifest.xml配置在apkplug框架中是无效的,我们需要在plugin.xml里面配置才能被apkplug所识别
具体设置属性为
Bundle-Activity=xxx.xxx.xxx.Activity
只有设置为Bundle-Activity的activity才能从宿主中启动,否则将报无法找到相应类的异常
二 设置多个外部启动Activity
如果你有多个activity需要从外部启动的话可以用,分割 如
Bundle-Activity=a.b.c,d.e.f,j.q.p
以上配置了三个activity,可以外部启动通过插件的Bundle.getBundleActivity() 可获取到这个字符串
Bundle.getBundleActivity().split(,)[0] 分割出对应的Activity类
三 启动activity
启动插件activity的方式很多,最简单的是以原生activity启动方式进行启动
Intent i=new Intent();
i.setClassName(mContext, Bundle.getBundleActivity().split(,)[0]);
//必须以此标签启动
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(i);
四 插件内部activity调用
以android原生方式调用即可.
须要注意的是所有插件activity都只能以 i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);方式启动android开发(43)
官网地址:/
先说下插件的配置,因为主程序要用到
插件的配置
首先在assets目录下添加plugin.xml文件
&?xml version=&1.0& encoding=&UTF-8&?&
&plugin-features
& & & & &Bundle-Name=&huanxindemo&
& & & & &Bundle-SymbolicName=&com.easemob.chatuidemo& &&
& & & & &Bundle-Version=&2.1.6&
& & & & &date=&&
& & & & &provider-name=&Apkplug&
& & & & &provider-url=&&
& & & & &Bundle-Activator=&com.easemob.chatuidemo.SimpleBundle&
& & & & &Bundle-Activity=&com.easemob.chatuidemo.activity.SplashActivity&
& & & & &&
&/plugin-features&
、、、要属性说明
Bundle-Name & & & & & & & & & & & &插件名称
Bundle-SymbolicName & & & 插件包名 &-与应用packagename可一一对应
Bundle-Version & & & & & & & & & & 插件版本 &-1.0.0
Bundle-Activator & & & & & & & & & &插件入口 &-与Appliction 类似
Bundle-Activity & & & & & & & & & & & 插件界面 &-多个Activity可用 , &分割
Bundle-Service & & & & & & & & & & 插件Service &-多个Service可用 , 分割 & &(v2.0.0新增)
Bundle-Receiver & & & & & & & & &插件广播 & &-多个广播类可用 , 分割 & & & & (v2.0.0新增)
第二:添加jar包libs/osgi2.8.0.jar
入口文件com.easemob.chatuidemo.SimpleBundle.java
package com.easemob.
import org.osgi.framework.BundleA
import org.osgi.framework.BundleC
import com.easemob.chatuidemo.activity.SplashA
import android.content.I
public class SimpleBundle implements BundleActivator
& & private BundleContext mcontext =
& & public void start(BundleContext context) throws Exception
& & & & System.err.println(&你好我是插件,我将为你展示启动acitivty我已经启动了 我的BundleId为:&+context.getBundle().getBundleId());
& & & & context.getBundleContext().startActivity(new Intent(context.getBundleContext(), SplashActivity.class));
& & public void stop(BundleContext context)
& && System.err.println(&你好我是插件,我被停止了 我的BundleId为:&+context.getBundle().getBundleId());
第一步,注册登录,就不说了
第二步:登陆后进入如图界面,我们点击上方的--应用授权--申请一个appid。填入对应的包名等即可。
第三:将申请好的appid复制到AndroidManifest.xml文件中。
配置应用权限
主应用需要几个基础的权限配置,请将以下的几个权限加入到主应用的AndroidManifest.xml中
&!-- 插件平台需要的权限! --&&
& & &uses-permission android:name=&android.permission.WRITE_EXTERNAL_STORAGE&&&/uses-permission&
& & &uses-permission android:name=&android.permission.MOUNT_UNMOUNT_FILESYSTEMS&/&&
& & &uses-permission android:name=&android.permission.INTERNET&/&
& & &uses-permission android:name=&android.permission.READ_PHONE_STATE&&&/uses-permission&
另外将一下加入到&application&&/application&节点中
&!-- 插件平台需要的配置! --&
& &&activity
& & & & & & android:name=&org.apkplug.app.apkplugActivity& &
& & & & & & android:theme=&@style/android:Theme.Light&
& & & & & & android:configChanges=&orientation|keyboardHidden&
最后将我们从Apkplug管理后台申请到的AppAuth加入到配置文件中,也就是第三步那个东西
&meta-data &android:name=&apkplug-auth& android:value=&xxxxxxxx& &&/meta-data&
需要注意的:
比如我们的插件为环信,我们还需要要环信需要的权限都添加到主程序里。。
还有对应的meta-data数据,比如环信的appkey也得写在这里。
第四:copy对应的jar包
libs/armeabi/libndkfoo.so
&libs/Bundle2.8.1.09-Release.jar
第五:将我们的插件apk放到assets目录下
插件的安装方法如下,红色方法参数的意义在代码里鼠标放上边可以自己看啥意思
private FrameworkInstance frame=
private void initplug(){
//启动框架
frame=FrameworkFactory.getInstance().start(null,this);
BundleContext context =frame.getSystemBundleContext();
InstallBundle ib=new InstallBundle(context);
ib.install(context,
&ChatUIDemo.apk&, &1.0.0&, new installCallback(){
public void callback(int arg0, Bundle arg1) {
if(arg0==installCallback.stutas5||arg0==installCallback.stutas7){
Log.d(&&,String.format(&插件安装 %s : %d&,arg1.getName(),arg0));
Log.d(&&,&插件安装失败 :%s&+arg1.getName());
2, false);
& & & &catch (Exception ex)
& & & & & &System.err.println(&Could not create : & + ex);
& & & & & &ex.printStackTrace();
& & & & & &int nPid = android.os.Process.myPid();
android.os.Process.killProcess(nPid);
附录:InstallBundle.java工具类如下
import java.io.BufferedOutputS
import java.io.F
import java.io.FileOutputS
import java.io.IOE
import java.io.InputS
import java.io.OutputS
import org.apkplug.Bundle.BundleC
import org.apkplug.Bundle.OSGIServiceA
import org.apkplug.Bundle.installC
import org.apkplug.app.FrameworkF
import org.apkplug.app.FrameworkI
import org.osgi.framework.BundleC
import org.osgi.framework.ServiceR
import android.content.C
import android.content.I
import android.content.SharedP
import android.util.L
&* 替代PropertyInstance.AutoStart()的功能
&* @author 梁前武
public class InstallBundle {
private SharedP
private SharedPreferences.E
public boolean DEBUG=
OSGIServiceAgent&BundleControl& agent=
public InstallBundle(BundleContext mcontext){
agent=new OSGIServiceAgent&BundleControl&(mcontext,BundleControl.class);
sp = mcontext.getAndroidContext().getSharedPreferences(&apkpluginstallconfig.ini&,0);
editor=sp.edit();
public void putString(String key, String value){
editor.putString(key, value);
public String getString(String key, String value){
return sp.getString(key,value);
* @param mcontext & &
* @param plugfile & & & &assets目录下的文件名 &如 drag-sort-listview.apk
* @param version & & & & 当前安装的插件版本号 & 如下次更新宿主时,可以提高这个版本好,以让框架安装最新宿主assets目录下的插件
* @param callback & & & &安装事件回掉接口
* @param startlevel & & &插件启动级别 小于2 插件会在框架启动时被自动启动
* @param isCheckVersion &是否对比当前安装的插件与已安装插件的版本好,如果为true时 新插件与已安装插件版本相同将不被更新。如果为false时将不检测版本直接覆盖已安装插件
* @throws Exception
public void install(BundleContext mcontext,String plugfile,String version,installCallback callback,int startlevel,boolean isCheckVersion) throws Exception{
// startlevel设置为2插件不会自启 isCheckVersion不检测插件版本覆盖更新
if(!DEBUG){
//不是调试模式
String PlugVersion=this.getString(plugfile,null);
if(PlugVersion!=null){
if(PlugVersion.equals(version)){
//如果本地已安装的插件版本等与目前插件的版本,那么就不安装了
InputStream in=mcontext.getAndroidContext().getAssets().open(plugfile);
f1=new File(mcontext.getAndroidContext().getFilesDir(),plugfile);
if(!f1.exists()){
copy(in, f1);
agent.getService().install(mcontext, &file:&+f1.getAbsolutePath(),callback, startlevel,isCheckVersion,false,false);
//安装完成后删除文件
f1.delete();
//将最新的插件版本号保存到本地
this.putString(plugfile, version);
InputStream in=mcontext.getAndroidContext().getAssets().open(plugfile);
f1=new File(mcontext.getAndroidContext().getFilesDir(),plugfile);
copy(in, f1);
agent.getService().install(mcontext, &file:&+f1.getAbsolutePath(),callback, startlevel,isCheckVersion,false,false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
* 将 assets目录下文件拷贝到文件夹中
* @param is
* @param outputFile
* @throws IOException
private void copy(InputStream is, File outputFile)
& & & &throws IOException
& & & &OutputStream os =
& & & &try
& & & & & &os = new BufferedOutputStream(
& & & & & & & &new FileOutputStream(outputFile),4096);
& & & & & &byte[] b = new byte[4096];
& & & & & &int len = 0;
& & & & & &while ((len = is.read(b)) != -1)
& & & & & & & &os.write(b, 0, len);
& & & &finally
& & & & & &if (is != null) is.close();
& & & & & &if (os != null) os.close();
第六步,启动,SplashActivity 为插件的启动页面
Intent i=new Intent();
i.setClassName(this,&com.easemob.chatuidemo.activity.SplashActivity&);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
说明,上边的启动的类就是我们插件里在 plunin.xml里的参数Bundle-Activity里对应的的activity。我们这里要启动哪个,那里就要写对应的哪个,可以有多个那里。
==============
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:33297次
排名:千里之外
原创:23篇
转载:24篇
(1)(2)(1)(1)(2)(2)(2)(1)(4)(8)(8)(1)(1)(6)(6)(2)> 博客详情
利用apkplug框架用插件生成的View动态替换(添加)宿主Activity中的UI元素,以实现无需更新宿主应用就改变宿主UI样式的目的
&&&& 时光匆匆,乍一看已半年过去了,经过这半年的埋头苦干今天终于有满血复活了。
利用apkplug框架实现动态替换宿主Activity中的UI元素,以达到不用更新应用就可以更换UI样式的目的。
先看效果图:
首先理解OSGI服务的基本概念,如下图
1.首先定义一个java接口(interface)用于规范宿主与插件之间的通讯协议
& interface& com.apkplug.osgi.service.showView
&&&&&&&&&&&&&&& void showView(Bundle bundle,View v,int index) ;& //添加View
&&&&&&&&&&&&&&& void removeView(Bundle bundle,View v);&&&&&&&&&&& //删除View
2.决定osgi服务提供者和使用者 ,这里我们定义是 宿主应用为"OSGI服务提供者",插件为"OSGI服务使用者"。
& 注:OSGI服务提供者 注册服务& OSGI服务使用者 查询服务
3.宿主应用实现showView接口,相应类为 com.apkplug.osgi.serviceImp.showViewImp 具体代码如下:
public class showViewImp implements showView{
private LinearLayout layout =
* @param root 插件 View保存UI容器
public showViewImp(View root){
this.layout=(LinearLayout)
public void showView(Bundle bundle, View v, int index) {
//当插件查找到服务并使用时回调
System.out.println("插件传来一个View");
layout.addView(v);
public void removeView(Bundle bundle, View v) {
System.out.println("插件需要删除一个View");
layout.removeView(v);
4.宿主应用将showViewImp以服务的形式注册都OSGI中,具体代码在com.apkplug.osgi.activity.ViewActivator中
&&&&&& 1:我们将宿主应用也虚拟为一个OSGI Bundle(插件) ,这样它便拥有了与其他插件进行OSGI通讯的条件。
&&&&&&&2:并且 宿主程序(插件)在框架启动的时候便被启动(这样showView服务就最先被注册上了,以后其他插件就可以查找到)
&&&& & 3:每一个OSGI Bundle都有一个实现BundleActivator
&& ViewActivator implements BundleActivator
public abstract interface BundleActivator
//插件启动时调用
public abstract void start(BundleContext context) throws E
//插件停止时调用
public abstract void stop(BundleContext context) throws E
由于ViewActivator代码较多这里只贴出与服务注册相关的代码
public void start(final BundleContext context) {
//注册一个服务给插件调用
m_reg = context.registerService(
showView.class.getName(),
5.编写插件,在插件的BundleActivator实现类中查询showView服务,并且初始化一个自身的View做为参数传递给宿主应用
& 插件的BundleActivator实现类为: com.apkplug.osgiclient1.SimpleBundle implements BundleActivator
查询showView服务的相关代码为:
//插件自定义View
myBtn=new myBtn(context.getBundleContext());
//查询主程序提供的showView服务
ServiceReference ref
context.getServiceReference(showView.class.getName());
获取Service实例
showView service
(showView) context.getService(ref);
调用Service方法
service.showView(context.getBundle(), myBtn, 0);
释放Service,在此之后不应该再继续使用Service实例
context.ungetService(ref);
总结: 经过以上步骤便完成了插件--&宿主的View对象传递并显示的过程。
结合OSGI服务我们通过自定义java接口类,并且适当转换OSGI服务者与使用者的角色来完成我们所需要的各种互交。
注:OSGI服务除了查询方式外,还提供监听器的方式(服务者可在使用者后启动注册服务) 详细demo也可参考osgiService的printLog服务注册与监听方式。
最后源码地址
人打赏支持
码字总数 27374
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥}

我要回帖

更多关于 fatjar插件下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信