zoukankan      html  css  js  c++  java
  • android 类加载器 DexClassLoader的用法,以及引出的插件架构

    1、android 类加载器(DexClassLoader的用法),调用其他apk的类中的方法:

    方式一:

       

    然后在Host中利用下面的方式调用

    PackageManager pm = getPackageManager();
            List<ResolveInfo> resolveInfos =  pm.queryIntentActivities(new Intent("com.haili.Plugin.client") , 0);
            ResolveInfo resolveInfo = resolveInfos.get(0);
            ActivityInfo activityInfo =resolveInfo.activityInfo;
    
            String packageName = activityInfo.packageName;
            String dexPath = activityInfo.applicationInfo.sourceDir; // 目标类所在的apk或jar所在的路径,加载器将在此目录寻找目标类
            String dexOutputDir = getApplicationInfo().dataDir; // dex包含在apk或者jar文件中,因此在装载目标类的时候需要先解压,此路径就是解压的路径
            String libPath = activityInfo.applicationInfo.nativeLibraryDir;  // 目标使用的一些C、C++库的路径
    
            DexClassLoader dexClassLoader = new DexClassLoader(dexPath , dexOutputDir , libPath ,this.getClass().getClassLoader());
    
        //利用java反射原理的方式来调用
            try {
                Class clazz = dexClassLoader.loadClass(packageName+"."+ "Plugin");
                Object object =  clazz.newInstance();
                Method method = clazz.getMethod("function" , Integer.TYPE ,Integer.TYPE);
                int addResult = (int) method.invoke(object ,12 ,34);
            }catch (Exception e)
            {
    
            }

    方式二:利用插件的方式来实现:

      1 、在host中定义comm的接口如下;然后生成外部jar包,然后必须以Library的方式添加到Plugin中,若以“外部jar方式”添加,jar会作为程序的一部分打包到最终文件中,导致Plugin和Host中有2份Comm(包名和类名相同),导致冲突,发生:Class ref in pre-verified class resolved to unexpected implementation错误。

     public interface Comm
    {
      public int function(int a , int b);
    }

      2、将Plugin的class的代码修改如下:

    public class Plugin implements Comm
    {
      ...  
        public int function(int a ,int b)
        {
           return a + b ;  
        }
    }

      3 、 在Host调用的时候

     PackageManager pm = getPackageManager();
            List<ResolveInfo> resolveInfos =  pm.queryIntentActivities(new Intent("com.haili.Plugin.client") , 0);
            ResolveInfo resolveInfo = resolveInfos.get(0);
            ActivityInfo activityInfo =resolveInfo.activityInfo;
    
            String packageName = activityInfo.packageName;
            String dexPath = activityInfo.applicationInfo.sourceDir; // 目标类所在的apk或jar所在的路径,加载器将在此目录寻找目标类
            String dexOutputDir = getApplicationInfo().dataDir; // dex包含在apk或者jar文件中,因此在装载目标类的时候需要先解压,此路径就是解压的路径
            String libPath = activityInfo.applicationInfo.nativeLibraryDir;  // 目标使用的一些C、C++库的路径
    
            DexClassLoader dexClassLoader = new DexClassLoader(dexPath , dexOutputDir , libPath ,this.getClass().getClassLoader());
    
        
          //利用插件的方式调用
            try
            {
                Class clazz = dexClassLoader.loadClass(packageName+"."+ "Plugin");
                Comm comm = (Comm)clazz.newInstance();
                int addResult = comm.function(12 , 34);
    
            }catch (Exception exception)
            {
            }

     二、插件架构

      所谓插件,就是由宿主车内光线调用插件,如浏览器的插件,浏览器就是Host,调用的插件Plugin:

      由上面利用插件架构的方式实现可以得出插件的基本概率和特点:

      

    主要结构:

      1、在Host中定义相关接口Comm,生成jar包以library的方式导入到Plugin中。

      2、Plugin中要实现插件功能相关的类中实现接口Comm.

      3、在Host 中用上面的方法加载plugin的类,并调用Plugin中实现的方法。

     Note:为了知晓有哪些插件,Host中可以为每一个插件定义一个特定的action字段,每个插件定义一个activity,并在插件Plugin中AndroidMainfest.xml清单文件定义一个空的activity,action设置为Host中插件的字段:这样Host就可以根据字段查询相应的插件从而查找相应的类和方法。

    插件和宿主的兼容性,插件的res/values/string中一般都会定义一些版本号以及一些名称信息,在Host中可以通过下面方法获取:

      

  • 相关阅读:
    HDUoj(1002)A + B Problem II
    HIT Summer 20180731
    Windows10下python3.5对维基百科语料用word2vec进行训练寻找同义词相似度
    关键词抽取
    win10+python遇到:Using TensorFlow backend.错误
    Windows下Python3.5+numpy+keras+tesorflow的环境配置
    常用的一些序列号
    Umbraco扩展开发
    Umbraco Content属性
    Windows查看端口占用
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/6667637.html
Copyright © 2011-2022 走看看