对于最简单例子的原理说明
发布于 1 年前 作者 apkplug 550 次浏览 来自 插件化

#最简单例子的原理说明

按照 Apkplug的一个最简单例子中的介绍,您能很快开发出一个基于Apkplug的工程,并进行快速体验。为了最简单的操作性,我们并未对原理性的东西进行说明,所以这里单独一篇来介绍其中涉及到的一些知识,使您了解为什么要这么做。

##1、权限配置

文档中要求的权限为sdk所需的权限,从权限本身即可知道,sdk会获取手机的一些状态和读写sd卡,其实主要就是这两方面,获取手机本身状态是为了收集设备标识,获取网络状态是为了网络监听和网络判断,从而实现偶尔断网或网络状态切换时还能继续下载。读写sd卡是为了文件的读写,这不用详细说明。

##2、manifest中标签的配置

manifest标签中需要配置mete data标签和组件标签。meta标签配置的是sdk和后台托管通信所需的信息,sdk需要appid和containerid这两个信息才能找到你后台托管的应用和其绑定的插件(更多相关概念)。组件标签是代理标签和merge进程的service标签。代理标签是为了代理插件中的组件,因为插件apk并未真正安装到系统,Android系统中启动组件要求必须是在一个真正安装的apk的manifest中配置过的,而宿主是不能事先判断插件有哪些组件的,所以我们会启动插件组件的时候我们会代理到这些代理标签中,让系统以为我们启动的是一个符合标准的组件,然后在真正创建组件的时候我们进行拦截,当我们判断是代理组件,则会根据传过来的附加信息转换成真正要启动的插件组件,这样就能成功绕过系统的检查。而merge进程的service组件则是为了合并差分文件和本地的,这里放到了另一个进程中。

##3、初始化sdk

这里就调用了一行代码,其实可以分成两部分理解,FrameworkFactory.getInstance().start(null,this)的调用是为了启动插件加载运行的核心框架,而最外层的PlugManager.getInstance().init调用则是外层服务代码的初始化,这些代码是为了和后台交互以及封装核心代码的一些api,这里传入的publickey是为了通信加密的。

##4、安装本地插件

这里举了最简单的例子,安装一个asstes中的apk,传入apk的名称是为了我们能从asstes中找到这个apk,版本号是为了判断是否重复安装,如果不在这里传入则需要解析apk才能得到,比较费时。最后传入的是安装监听,可以在这里收到安装成功失败等状态的回调。如下是例子工程安装插件的具体代码:

    InstallBundler ib=new   InstallBundler(FrameworkFactory.getInstance().getFrame().getSystemBundleContext());
    ib.Debug(true); //设置为调试模式, 在调试模式下才会重复安装assets目录下的apk文件, 而非调试模式下只会安装一次
    InstallInfo installinfo =new InstallInfo();
    installinfo.isInstallAPK=true;  //设置可以安装普通的apk文件 , apkplug默认情况只能安装含有assets/plugin.xml的apk文件,因此对于普通的apk文件需要配置这个参数为true
    ib.installForAssets("hello_plug-debug.apk", "100", installinfo,new installCallback(){
        //在非调试模式下 只有String assetsName, String version 这两个变量改变才会重新执行安装流程
        @Override
        public void callback(int arg0, org.osgi.framework.Bundle arg1) {
            //Log.e("status改动了一点点",""+arg0);
            if(arg0==installCallback.success_install){
                textView.setText("hello_plug安装成功");
            }else if(arg0==installCallback.success_update){
                textView.setText("hello_plug更新成功");
            }else if(arg0==installCallback.error_cache_not_updated){
                textView.setText("hello_plug已安装过,且assetsName和version都未改变,不执行安装流程。" +
                        "\n测试环境可以将InstallBundler.Debug(true)让框架每次都重新安装这个apk");
            }
        }
    });

##5、启动插件activity

当你成功安装一个插件后,就可以正常启动这个插件的activity了,不用担心插件并未真正安装,从前面第二项标签配置中的说明可以知道,我们已经用hook的方式对activity的启动进行了监听拦截转换,这些都是你不需要考虑的。如下是例子中的具体代码:

    //获得所有apkplug中的插件对象
            org.osgi.framework.Bundle[] all_bundles=FrameworkFactory.getInstance().getFrame().getSystemBundleContext().getBundles();
            org.osgi.framework.Bundle plug=all_bundles[1]; //取出第二个插件, 因为第一个插件永远是由apkplug自动生成的SystemBundle
            String plugMianActivity=plug.getBundleActivity().split(",")[0]; //获取插件的启动Activity
            Intent intent=new Intent();
            intent.setClassName(MainActivity.this,plugMianActivity);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);

##6、总结

经过上面几步的原理说明,您大概知道为什么要这么做了,尽管过程很简单,但是其背后是有sdk强大的技术支持的,同时也经过了我们大量的测试,您可以简单、放心的使用。

##7、例子工程源码 https://github.com/apkplug/SDKDemo/tree/master/apkplug_examples

回到顶部