zoukankan      html  css  js  c++  java
  • Android插件化开发之OpenAtlas生成插件信息列表

    上一篇文章。[Android插件化开发之Atlas初体验](
    http://blog.csdn.net/sbsujjbcy/article/details/47446733),简单的介绍了使用Atlas的整个流程,可是假设你没有实践过的话预计还是一头雾水。从这篇文章開始,慢慢的切入细节。这篇文章的主题是生成插件信息列表。

    细心的你也许发现了上篇文章中我们使用了一个叫openatlasbundler的项目生成了so以及一个json文件,说白了这个so仅仅只是就是apk重命名的。而这个json文件里包括了插件的信息。比方上篇文章中的两个插件,其信息例如以下。

    [
      {
        "pkgName": "com.lizhangqu.test",
        "version": "1.0",
        "activities": [
          "com.lizhangqu.test.MainActivity"
        ],
        "services": [],
        "receivers": [],
        "contentProviders": [],
        "dependency": [],
        "md5": "882d50a3c2668360b96a3af8f72b3bd2",
        "size": 24780,
        "hasSO": false
      },
      {
        "pkgName": "com.lizhangqu.zxing",
        "version": "1.0",
        "activities": [
          "com.lizhangqu.zxing.android.CaptureActivity"
        ],
        "services": [],
        "receivers": [],
        "contentProviders": [],
        "dependency": [],
        "md5": "e68270557ae9776d218bb034916c124a",
        "size": 312352,
        "hasSO": false
      }
    ]

    能够看到里面存了插件的一些组件信息。以及大写和md5等。

    依照作者原话说是这种。

    BundleList的生成。这部分用的Java写的,BundleListInfo一个存储json的文本文件,我们所做的这一切无非是提高效率,举个样例。你安装插件的时候假设有动态库的话要解压。不能安装的时候每个文件检測一下apk存在so不。打开文件本来就慢。程序优化一点是一点

    我们能够试试,假设不将该so文件打包进去,程序执行会出现什么。

    这里写图片描写叙述

    这里写图片描写叙述

    这里写图片描写叙述
    我们发现,打印了一个日志说找不到插件信息列表。

    至于插件信息列表的读取。这里姑且不去理会,本篇的重点是怎样生成该列表。

    打开BundleMakeBooter类,里面就一个main函数,也就是说这个仅仅只是是普通的java项目,事实上我们能够从命令行将參数传入,可是还记得上篇文章我们将前三行代码凝视掉,增加了三行写死的代码。

    args=new String[2];
    args[0]="C:\Users\kltz\Desktop\AtlasDemo\plugin";
    args[1]="C:\Users\kltz\Desktop\AtlasDemo\plugin\bundle-info.json";

    数组第一个參数代表待处理的apk所在文件夹,数组第二个參数代表生成的插件信息存的文件。而我们是在项目根文件夹建立一个文件夹叫plugin,后来将插件的apk都拷贝到该文件夹进行处理。

    main函数中開始调用了ApkPreProcess.preProcess(path);将第一个參数传入,该函数所做的事事实上非常easy,就是将apk重命名为so,怎么个重命名法呢。

    首先遍历该文件夹,得到以apk后缀的文件,通过解析拿到该apk的包名,将该apk命名为lib开头。后面紧跟包名。包名中的.会被替换成_。最后文件后缀是so,假设该文件夹存在了该so,则将原so文件删除。然后将apk重命名。就是这么简单。

    看代码

    public static void preProcess(String mDir) {
            Collection<File> apkFiles = org.apache.commons.io.FileUtils.listFiles(new File(mDir), new String[]{"apk"}, true);
    
            for (File file : apkFiles) {
                String pkgName = PackageLite.parse(file.getAbsolutePath()).packageName;
    
                pkgName = "lib" + pkgName.replaceAll("\.", "_") + ".so";
                File targetFile = new File(mDir + File.separator + pkgName);
                if (targetFile.exists())
                    targetFile.delete();
    
                System.out.println("rename: " + file.getName() + " -> " + pkgName);
                while(!file.renameTo(targetFile)) {
                    System.gc();
                    Thread.yield();
                }
                System.out.println("ApkPreProcess.preProcess() processed " + pkgName);
            }
        }

    重命名完毕后接下来就是遍历该文件夹,查找以libcom_开头的的文件,注意这里是一个约定,就是包名以com开头。

    然后通过PackageLite.parse()函数解析每个so。通过packageLit.getBundleInfo()函数获得解析结果并将其扔到一个json数组中去。最后将该json数组写入文件。也就是args数组第二个參数指定的内容。

    置于怎样解析,这里不做展开了,代码太长。事实上这个已经涉及到反编译的范畴了,事实上该项目的一大部分源代码是AXMLPrinter的源代码。一个android xml反编译的东西,这里提供源代码下载AXMLPrinter。 倒是能够看看getBundleInfo()函数

    public JSONObject getBundleInfo() throws JSONException {
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("pkgName", packageName);
            jsonObject.put("version", versionName);
            JSONArray activityArray=new JSONArray();
            for (String name:activitys) {
                activityArray.put(name);
            }
            jsonObject.put("activities", activityArray);
            JSONArray servicesArray=new JSONArray();
            for (String name:services) {
                servicesArray.put(name);
            }
            jsonObject.put("services", servicesArray);
            JSONArray receiversArray=new JSONArray();
            for (String name:receivers) {
                receiversArray.put(name);
            }
            jsonObject.put("receivers", receiversArray);
    
            JSONArray providersArray=new JSONArray();
            for (String name:providers) {
                providersArray.put(name);
            }
            jsonObject.put("contentProviders", providersArray);
            JSONArray dependencyArray=new JSONArray();
            for (String name:dependency) {
                dependencyArray.put(name);
            }
            jsonObject.put("dependency", dependencyArray);
            jsonObject.put("md5", apkMD5);
            jsonObject.put("size", size);
            jsonObject.put("hasSO", hasSO);
    
            return jsonObject;
    
        }

    事实上就是将解析结果转化为json。非常easy有木有。

    注意生成的json文件的文件名称要为bundle-info.json,当然你也能够通过改动代码使用别的文件名称,然后该文件要放在assets文件夹下。

    解析该json文件的代码在openatlascore项目中的BundleParser类中的parser函数中,有兴趣能够先去看看。

    接下来要做的事就是将该json打包进apk,把so放到相应文件夹。即armeabi文件夹下,依照作者的原话就是加快启动速度,能够见这个issue插件能够不放在主project的libs/armeabi目錄下麼

    还有,赶紧亲自试一试吧,仅仅要亲自试过了之后,才会认为,哦。原来是这么一回事啊。

    什么,源代码。木有源代码,代码见上一篇文章末尾[Android插件化开发之Atlas初体验](
    http://blog.csdn.net/sbsujjbcy/article/details/47446733)

  • 相关阅读:
    Linux C Socket编程原理及简单实例
    clock_gettime 用法
    Linux未来监控tracing框架——eBPF
    eBPF监控工具bcc系列五工具funccount
    【转】如何测量电源纹波?
    【转】在网页中运行VB6程序
    如何为互阻抗放大器电路选择具有足够带宽的运算放大器
    互阻放大器的稳定工作及其评估
    【原创】OPA857 TEST模式使用
    [转]What you need to know about transimpedance amplifiers – part 1
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7278477.html
Copyright © 2011-2022 走看看