Android之ClassLoader和插件

Stella981
• 阅读 636

Android之ClassLoader和插件

Android中的ClassLoader本质上跟JRE中的一样,但Android的字节码格式不一样,Android下的ClassLoader不能直接加载普通的jar包,需要使用dex2jar工具中的d2j-jar2dex.bat,  把jar转换为classes.dex,然后把classes.dex放到jar文件中作为ClassLoader的源数据;

1)我们先生成一个Android需要的JAR;
源码:

package test;

public class AnPluginDemo {
   public int getValue() {
      return 100;
   }
}

2)打包成jar;
3)使用dex2jar工具中的d2j-jar2dex.bat, 把jar转换为classes.dex;
4)把classes.dex放到一个新的jar中, AnPluginDemo.jar;
5)建立一个Android工程;
6)把AnPluginDemo.jar放到assets下;
7)加载插件并运行

void loadAndInvoke(String name) {
      try {
         File dir = getDir("plugin", Context.MODE_PRIVATE);

         byte[] bs = readDataFromAsserts("plugin/" + name);// 读取插件数据
         String path = new File(dir, name).getAbsolutePath();// 插件保存的位置
         Files.writeFile(path, bs);// 保存插件

         // 创建类加载器,把dex加载到虚拟机中
         DexClassLoader loader = new DexClassLoader(//
               path,//插件路径,可以用冒号分隔多个,  可以是jar(内有classes.dex)或apk格式
               dir.getAbsolutePath(),//优化后保存的目录
               null,//so文件位置
               this.getClass().getClassLoader()//父ClassLoader
         );

         Class<?> c = loader.loadClass("test/AnPluginDemo");// 加载需要使用的类
         Method m = c.getMethod("getValue");// 取得方法
         Object o = c.newInstance();// 创建对象
         Object r = m.invoke(o);// 调用方法
         showTipDialog("R:" + r);//显示执行结果
      } catch (Exception e) {
         e.printStackTrace();
         showTipDialog("R:" + e.getClass());
      }
   }
点赞
收藏
评论区
推荐文章
刘望舒 刘望舒
2年前
Android包管理机制(一)PackageInstaller的初始化
Android框架层Android包管理机制Android框架层本文首发于微信公众号「刘望舒」前言包管理机制是Android中的重要机制,是应用开发和系统开发需要掌握的知识点之一。包指的是Apk、jar和so文件等等,它们被加载到Android内存中,由一个包转变成可执行的代码,这就需要一个机制来进行包的加载、解析、管理等操作,这就是包管理机制。包管理
东方客主 东方客主
3年前
Android动态加载基础 ClassLoader工作机制
类加载器ClassLoader早期使用过Eclipse等Java编写的软件的同学可能比较熟悉,Eclipse可以加载许多第三方的插件(或者叫扩展),这就是动态加载。这些插件大多是一些Jar包,而使用插件其实就是动态加载Jar包里的Class进行工作。这其实非常好理解,Java代码都是写在Class里面的,程序运行在虚拟机上
Stella981 Stella981
2年前
ClassLoader解惑
一、什么是Classloader    一个Java程序要想运行起来,首先需要经过编译生成.class文件,然后创建一个运行环境(jvm)来加载字节码文件到内存运行,而.class文件是怎样被加载中jvm中的就是JavaClassloader所做的事情。    那么.class文件什么时候会被类加载器加载到j
Stella981 Stella981
2年前
SpringBoot使用RedisTemplate操作Redis时,key值出现 -xac-xed-x00-x05t-x00-tb
原因分析原因与RedisTemplate源码中的默认序列化方式有关defaultSerializernewJdkSerializationRedisSerializer(classLoader!null?classLoader:this.getClass().getClassLoader()
Stella981 Stella981
2年前
Android 插件化原理解析——Activity生命周期管理
在Java平台要做到动态运行模块、热插拔可以使用ClassLoader技术进行动态类加载,比如广泛使用的OSGi技术。在Android上当然也可以使用动态加载技术,但是仅仅把类加载进来就足够了吗?Activity,Service等组件是有生命周期的,它们统一由系统服务AMS管理;使用ClassLoader可以从插件中创建Activit
Stella981 Stella981
2年前
Eclipse Spring Boot实现热部署
spring为开发者提供了一个名为springbootdevtools的模块来使SpringBoot应用支持热部署,提高开发者的开发效率,无需手动重启SpringBoot应用。devtools的原理深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更
Stella981 Stella981
2年前
Android ClassLoader加载过程源码分析
背景Android开发过程中,开发的小伙伴对动态加载代码肯定不陌生。使用各个开源框架的中都应该有接触,其主要原理离不开ClassLoader等相关的类。这里我们会从Android中ClassLoader等相关类的源码入手,更好的理解和学习动态加载类的原理。详细分析ClassLoader加载原理Clas
Stella981 Stella981
2年前
Android版添加phonegap
1.下载插件包。2\.解压所下载的包,从lib目录中得到所需要的所有的库:BaiduSocialShareSDKAndroid2.0.0.jar3\.修改AndroidManifest.xml,增加以下权限:<usespermissionandroid:name"android.permiss
Easter79 Easter79
2年前
SpringBoot使用RedisTemplate操作Redis时,key值出现 -xac-xed-x00-x05t-x00-tb
原因分析原因与RedisTemplate源码中的默认序列化方式有关defaultSerializernewJdkSerializationRedisSerializer(classLoader!null?classLoader:this.getClass().getClassLoader()
Stella981 Stella981
2年前
Android动态加载之ClassLoader详解
Dalvik虚拟机如同其他Java虚拟机一样,在运行程序时首先需要将对应的类加载到内存中。而在Java标准的虚拟机中,类加载可以从class文件中读取,也可以是其他形式的二进制流。因此,我们常常利用这一点,在程序运行时手动加载Class,从而达到代码动态加载执行的目的。只不过Android平台上虚拟机运行的是Dex字节码,一种对class文件优化的产物