精华内容
下载资源
问答
  • DexClassLoader

    2015-11-30 16:35:41
     DexClassLoader classLoader = new DexClassLoader(file.getAbsolutePath(),  dexOutputDir.getAbsolutePath(), null, context.getClassLoader());  Class<?> clazz = classLoader.loadClass(mClassName);...
    Context context=getApplicationContext();
    // TODO Auto-generated method stub
    String mJarPath = android.os.Environment.getExternalStorageDirectory()
           .getAbsolutePath() + "/o.jar";
    String    mClassName = "txst.DataBindImpl";

       File dexOutputDir = context.getDir("dex", 0);//

    String dexOutputDir = context.getApplicationInfo().dataDir;//

       File file = new File(mJarPath);
       DexClassLoader classLoader = new DexClassLoader(file.getAbsolutePath(),
           dexOutputDir.getAbsolutePath(), null, context.getClassLoader());
         Class<?> clazz = classLoader.loadClass(mClassName);
         Object obj = clazz.newInstance();  
         DataBind dataBind=(DataBind) obj;
    int s=  dataBind.dataBind();
    展开全文
  • 关于DexClassLoader

    千次阅读 2019-07-05 10:07:58
    安卓的动态加载必备知识之一,DexClassLoaderDexClassLoader当然也是一种ClassLoader,但本身属于顾名思义是用来加载Dex文件的,是安卓系统独有的一种类加载器。 基础概念 在此之前可以稍微回顾下ClassLoader的...

    安卓的动态加载必备知识之一,DexClassLoader。
    DexClassLoader当然也是一种ClassLoader,但本身属于顾名思义是用来加载Dex文件的,是安卓系统独有的一种类加载器。

    基础概念

    在此之前可以稍微回顾下ClassLoader的相关基础:

    • ClassLoader是用来加载class文件的,它负责将*.class加载为内在中的Class对象
    • 加载机制为“双亲委派”,即能交给父类加载器去加载的,绝不自行加载

    再来看DexClassLoader:
    dexclassloader
    官方说明了DexClassLoader的定义:

    • 用于加载包含*.dex文件的jar包或apk文件
    • 要求一个应用私有可写的目录去缓存编译的class文件
    • 不允许加载外部存储空间的文件,以防注入攻击

    那么很明显,我们普通项目中的jar包是不能直接用来加载的了。
    在Java项目中,一般加载jar包会使用URLClassLoader,但安卓davlik不能使用,安卓只能使用继承自BaseDexClassLoader的两种ClassLoader—一种是PathClassLoader,用于加载系统中已经安装的apk;一种就是DexClassLoader,加载未安装的jar包或apk。

    所以如果在安卓系统上想要动态加载jar包,DexClassLoader可能是唯一的选择。
    DexClassLoader源码

    使用方法

    使用很简单,只需要清楚其构造方法的参数意义就可以。

    DexClassLoader (String dexPath, 
                    String optimizedDirectory, 
                    String librarySearchPath, 
                    ClassLoader parent)
    
    参数 含义
    dexPath 包含dex文件的jar包或apk文件路径
    optimizedDirectory 释放目录,可以理解为缓存目录,必须为应用私有目录,不能为空
    librarySearchPath native库的路径,可为空
    parent 父类加载器

    那么使用起来就是这样:

    	private void loadJar1(){
            String file = Environment.getExternalStorageDirectory() + "/jinxingateway/jar/codec.jar";
            String path = getDir("jar", MODE_PRIVATE).getAbsolutePath() + File.separator + "codec.jar";
    		try {
    			//复制到私有目录
                FileOperator.copy(file, path);
    
                DexClassLoader dcl = new DexClassLoader(path, getDir("jar", MODE_PRIVATE).getAbsolutePath(), null, getClassLoader());
    
                Class<?> factoryCls = dcl.loadClass("com.jinxin.codec.ProtocolCodecFactory");
                Class<?> extensionCls = dcl.loadClass("com.jinxin.codec.ICodecExtension");
    
    			//省略其下利用反射的代码
    		} catch (IOException e) {
                e.printStackTrace();
    		} catch (ClassNotFoundException e) {
                e.printStackTrace();
    		} catch (NoSuchMethodException e) {
                e.printStackTrace();
    		} catch (InstantiationException e) {
                e.printStackTrace();
    		} catch (IllegalAccessException e) {
                e.printStackTrace();
    		} catch (InvocationTargetException e) {
                e.printStackTrace();
    		}
    	}
    

    因为读写权限的敏感,所以jar包一般也会复制到应用私有路径中再行加载,加载后使用loadClass方法即可得到类,然后利用反射就可以得到类中的各种信息了。

    这里的加载是不能使用Class.forName的,因为这样使用最终调用的就是java的ClassLoader而不是DexClassLoader了:

        public static Class<?> forName(String className)
                    throws ClassNotFoundException {
            return forName(className, true, VMStack.getCallingClassLoader());
        }
    

    扩展

    DexClassLoader只能加载dex,那普通的jar包怎么办?
    当然是转成dex了。
    使用安卓sdk/build-tools目录下的dx工具,即可把普通的jar包转换为包含dex的jar包。在能运行dx.bat的情况下使用命令:

    dx  --dex --output [输出文件] [输入文件]
    
    展开全文
  • DexClassLoader 研究

    2017-06-01 16:28:35
    DexClassLoader PackageInfo ClassLoader Class Contructor Method - ...
    展开全文
  • DexClassLoader简介

    2016-03-03 11:02:52
    DexClassLoader简介

    DexClassLoader简介


         了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用的。我们知道,java程序可以动态加载类定义,而这个动态加载的机制就是通过ClassLoader来实现的,所以可想而知ClassLoader的重要性如何。 

    ClassLoader的分类和基本的加载流程:

     bootstrap classloader:

    既然ClassLoader是用来加载类到JVM中的,那么ClassLoader又是如何被加载呢?难道它不是java的类? 没有错,在这里确实有一个ClassLoader不是用java语言所编写的,而是JVM实现的一部分,这个ClassLoader就是bootstrap classloader(启动类加载器),这个ClassLoader在JVM运行的时候加载java核心的API以满足java程序最基本的需求,核心API里面也包括了以下两种用java实现的ClassLoader

    ExtClassLoader:

    一个Classloader就是ExtClassLoader。这个ClassLoader是用来加载java的扩展API的,也就是/lib/ext中的类。

    AppClassLoader:

    另一个是AppClassLoader,这个ClassLoader是用来加载用户机器上CLASSPATH设置目录中的Class的,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载。 

         当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。 

    ClassLoader的双亲委托加载模式:

    先给出一段使用classloader的一段代码:

    @SuppressLint("NewApi")  
        public void test() {  
            // dex下载的位置--可以是内部存储或外部存储位置  
            File dexInputFile = new File(Environment.getExternalStorageDirectory().toString() + File.separator  
                    + "elvis_plugin_dex_sayhello.jar");  
            String dexInputFileDir = dexInputFile.getAbsolutePath();  
            // dex输出位置--只能是内部存储位置  
            String dexOutputFileDir = getFilesDir().getAbsolutePath();  
            // dexClassLoader对象  
            DexClassLoader dexClassLoader = new DexClassLoader(dexInputFileDir, dexOutputFileDir, null,  
                    this.getClass().getClassLoader());  
            // 利用反射调用插件包内的类的方法  
            try {  
                Class<?> clazz = dexClassLoader.loadClass("com.elvis.plugin.sayhello.SayHello");  
                Object obj = clazz.newInstance();  
                // //设置参数格式  
                // Class[] param = new Class[2];  
                // param[0] = Integer.TYPE;  
                // param[1] = Integer.TYPE;  
                Method method = clazz.getMethod("say");  
                // method.invoke(obj,1,12);  
                method.invoke(obj);  
            } catch (ClassNotFoundException e) {  
                Log.e("elvis", "ClassNotFoundException");  
                e.printStackTrace();  
            } catch (InstantiationException e) {  
                Log.e("elvis", "InstantiationException");  
                e.printStackTrace();  
            } catch (IllegalAccessException e) {  
                Log.e("elvis", "IllegalAccessException");  
                e.printStackTrace();  
            } catch (NoSuchMethodException e) {  
                Log.e("elvis", "NoSuchMethodException");  
                e.printStackTrace();  
            } catch (IllegalArgumentException e) {  
                Log.e("elvis", "IllegalArgumentException");  
                e.printStackTrace();  
            } catch (InvocationTargetException e) {  
                Log.e("elvis", "InvocationTargetException");  
                e.printStackTrace();  
            }  
        }  

    我们可以发现classloader的关键两条API是:

    DexClassLoader dexClassLoader = new DexClassLoader(dexInputFileDir, dexOutputFileDir, null,this.getClass().getClassLoader());

    Class<?> clazz = dexClassLoader.loadClass("com.elvis.plugin.sayhello.SayHello");

    首先,每个ClassLoader都会有一个parent ClassLoader,当实例化子classLoader时必须传入parent ClassLoader,若null,那么就默认该ClassLoader的parent是bootstrap classloader。

    双亲委托模式:

    在任何一个自定义ClassLoader加载一个类之前,它都会先委托它的父亲ClassLoader进行加载,只有当父亲ClassLoader无法加载成功后,才会由自己加载

    这里给出了loadclass函数源码API:(这里就可以详细看到关于双亲委托模式的实现)

        /**
         * Loads the class with the specified name, optionally linking it after
         * loading. The following steps are performed:
         * <ol>
         * <li> Call {@link #findLoadedClass(String)} to determine if the requested
         * class has already been loaded.</li>
         * <li>If the class has not yet been loaded: Invoke this method on the
         * parent class loader.</li>
         * <li>If the class has still not been loaded: Call
         * {@link #findClass(String)} to find the class.</li>
         * </ol>
         * <p>
         * <strong>Note:</strong> In the Android reference implementation, the
         * {@code resolve} parameter is ignored; classes are never linked.
         * </p>
         *
         * @return the {@code Class} object.
         * @param className
         *            the name of the class to look for.
         * @param resolve
         *            Indicates if the class should be resolved after loading. This
         *            parameter is ignored on the Android reference implementation;
         *            classes are not resolved.
         * @throws ClassNotFoundException
         *             if the class can not be found.
         */
        protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
            Class<?> clazz = findLoadedClass(className);
    
            if (clazz == null) {
                ClassNotFoundException suppressed = null;
                try {
                    clazz = parent.loadClass(className, false);
                } catch (ClassNotFoundException e) {
                    suppressed = e;
                }
    
                if (clazz == null) {
                    try {
                        clazz = findClass(className);
                    } catch (ClassNotFoundException e) {
                        e.addSuppressed(suppressed);
                        throw e;
                    }
                }
            }
    
            return clazz;
        }


    DexClassLoader的使用:

    请见我的博文:http://blog.csdn.net/qq979418391/article/details/50578607


    DexClassLoader的深入解读:

    关于Class.forName方法与loadClass方法的区别:http://www.iteye.com/topic/83978






    展开全文
  • DexClassLoader_Dex-源码

    2021-05-03 06:20:03
    DexClassLoader_Dex 使用DexClassLoader加载第三方dex进行调用其中的方法
  • DexClassLoader加载流程

    2020-09-22 15:40:52
    总结:过程中出现dex起始...还是先来到DexClassLoader的初始化函数 路径:8.0.0_r4/xref/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java public class DexClassLoader extends BaseDexClassLoader
  • DexClassLoader 插件

    2016-03-24 00:48:45
    final File optimizedDexOutputPath = new File("/data/data/com.example.test"  + File.separator + "test.jar");    DexClassLoader cl = new DexClassLoader(op
  • Android DexClassLoader

    2016-06-25 14:59:07
    DexClassLoader 是Android SDK里面的,它的相关描述可参考官方文档:  http://www.android-doc.com/reference/dalvik/system/DexClassLoader.html 当APP里面的功能太多时,后期的开发或升级时通常采用插件化的...
  • DexClassLoader的调用

    2015-07-30 11:04:40
    android中DexClassLoader的使用方式
  • android_dex Android DexClassLoader
  • DexClassLoader动态加载分析

    千次阅读 2017-04-21 11:46:12
    看到原来有把原始的dex文件加密保存,然后解密后使用DexClassLoader加载文件的方法,就来分析下DexClassLoader的加载流程: 源码地址:http://androidxref.com/4.4_r1/xref/libcore/dalvik/src/main/java/d
  • 在Android中可以跟java一样实现动态加载jar,但是Android使用Dalvik VM,不能直接加载java打包jar的byte code,需要通过dx工具来优化Dalvik byte codeAndroid在API中给出可动态加载的有:DexClassLoader 和 ...
  • Android dexclassLoader 热更demo,详细讲解请看 https://blog.csdn.net/zhou3299136/article/details/105796479
  • Android DexClassLoader调用其他apk中的函数 实现动态加载
  • 本文简单介绍 热修复的一种实现,插件化原理也可以参考。 Android系统中的类加载器 Android系统屏蔽了ClassLoader的findClass加载方法,那么它自己的类加载时...PathClassLoader和DexClassLoader都是继承与B...
  • 详细解读 PathClassLoader 和 DexClassLoader 的区别
  • 主要介绍了Android开发中类加载器DexClassLoader的简单使用讲解,DexClassLoader可以看作是一个特殊的Java中的ClassLoader,需要的朋友可以参考下
  • DexClassLoader 刷新问题

    千次阅读 2016-04-07 21:04:46
    1、DexClassLoader加载上某个APK或jar 2、更新上面的APK或JAR,再次通过DexClassLoader 加载 3、显式调用GC或系统触发GC时闪退 存在于4.X的系统中。 解决方案,在进程生命周期内如需要更新dex,请将源APK或JAR...
  • ClassLoader,DexClassLoader,PathClassLoader 区别
  • DexClassLoader学习源码,使用时,请删除Lib.Java文件,否则会出现loadClass错误。
  • android PathClassLoader DexClassLoader BaseDexClassLoader Android类加载器: BootClassLoader,URLClassLoader,PathClassLoader,DexClassLoader,BaseDexClassLoader等最终都继承自java.lang.ClassLoader,//1、...
  • 直接说操作 File optDex = context.getDir("opt_dex", 0);... DexClassLoader dexClassLoader = new DexClassLoader(dexPath, optDex.getAbsolutePath(), libPath.getAbsolutePath(), MainActivity.this.g
  • DexClassLoader的使用

    2015-08-26 19:44:48
    DexClassLoader此处用于从一个应用调用另外一个插件apk的用法: 在插件apk中定义方法: public class PluginClass { public PluginClass() { Log.i("Plugin", "PluginClass client initialized"); } public ...
  • android-custom-class-loading-sample,源码。需要使用ant进行编译。编译之后可以动态的使用DexClassLoader加载代码并执行。
  • 前言:最近在研究安卓的加壳和脱壳,发现遇到知识盲区,是以前的windows研究的时候好多没遇到的,...DexClassLoader dexClassLoader = new DexClassLoader("/sdcard/Dex.dex",optfile.getAbsolutePath(), libfile.getA
  • DexClassLoader实现加壳

    千次阅读 2015-05-01 13:00:32
    dexclassloader 解决组件类生命周期问题
  • PathDexClassLoader 和 DexClassLoader 区别 PathClassLoader: Provides a simple ClassLoader implementation that operates on a list of files and directories in the local file system, but does not...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 811
精华内容 324
关键字:

dexclassloader