apkplug使用体验

来源:互联网 发布:淘宝每天访客多少正常 编辑:程序博客网 时间:2024/06/14 14:54

官网地址:http://www.apkplug.com/

先说下插件的配置,因为主程序要用到

插件的配置

首先在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="2015.3.12"
         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.chatuidemo;


import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;


import com.easemob.chatuidemo.activity.SplashActivity;


import android.content.Intent;


public class SimpleBundle implements BundleActivator
{
    private BundleContext mcontext = null;
    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=null;
private void initplug(){
try
       {
        //启动框架
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(){
@Override
public void callback(int arg0, Bundle arg1) {
if(arg0==installCallback.stutas5||arg0==installCallback.stutas7){
Log.d("",String.format("插件安装 %s : %d",arg1.getName(),arg0));
}
else{
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.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


import org.apkplug.Bundle.BundleControl;
import org.apkplug.Bundle.OSGIServiceAgent;
import org.apkplug.Bundle.installCallback;
import org.apkplug.app.FrameworkFactory;
import org.apkplug.app.FrameworkInstance;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;


import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
/**
 * 替代PropertyInstance.AutoStart()的功能
 * @author 梁前武
 */
public class InstallBundle {
private SharedPreferences sp;
private SharedPreferences.Editor editor;
public boolean DEBUG=true;
OSGIServiceAgent<BundleControl> agent=null;
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);
editor.commit();
}
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不检测插件版本覆盖更新
File f1=null;
try {

if(!DEBUG){
//不是调试模式
String PlugVersion=this.getString(plugfile,null);
if(PlugVersion!=null){
if(PlugVersion.equals(version)){
//如果本地已安装的插件版本等与目前插件的版本,那么就不安装了
return ;
}
}
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);
}else{
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 = null;


       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。我们这里要启动哪个,那里就要写对应的哪个,可以有多个那里。


==============


0 0