Android反射使用

本文介绍了Android中的反射机制,如何在运行时加载不确定的类并使用其成员和方法。反射有助于在合作开发中减少对其他模块依赖的影响。详细讨论了Java虚拟机的工作原理以及ClassLoader的角色,特别是PathClassLoader和DexClassLoader的区别,后者能够加载外部APK、JAR或DEX文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于java语言的开发,可以使用其反射机制:在程序运行时,加载编译时并不确定的类,使用这些类的成员和方法。

反射的作用:解决合作开发时,自身编程不受合作方的进度、变更影响,实现自身代码编译。

反射的工作原理:当一个类被加载以后,Java虚拟机就会自动产生一个Class对象;通过加载所需的类到虚拟机,

进而获取虚拟机产生的Class对象;最后使用这个Class对象对应的构造方法、成员、方法等声明和定义的信息。

基于JVM虚拟机的动态加载器ClassLoader的使用:

//定义一个测试类,用来被反射调用
package com.grandshow;
public class Test {
    private String str;

    public Test(String s) {
        this.str = s;
    }

    public void show() {
        System.out.println(str);
    }

}
package com.grandshow;
import java.lang.reflect.Constructor;

public class Client {

    public static void main(String[] s) {
        try {
        //获取动态加载器ClassLoader,加载Class到虚拟机,返回一个Class对象clazz 
            Class clazz = ClassLoader.getSystemClassLoader().loadClass(
                    "com.grandshow.Test");
        //通过clazz 获取构造方法并生成对象
            Constructor constructor = clazz.getConstructor(String.class);
            Object obj = constructor.newInstance("GrandShow");
        //通过clazz 获取成员方法并执行
            Method method = clazz.getMethod("show", null);
            method.invoke(obj, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
基于DVM虚拟机的Android,则使用dalvik.system.DexClassLoader 和 dalvik.system.PathClassLoader类加载器。

主要区别在于 PathClassLoader 只能直接操作 dex 文件或者已经安装过的 apk;而 DexClassLoader 则可以

加载外部的 apk、jar 或 dex文件,并会在指定的 outpath 路径存放其 dex 文件。

DexClassLoader:

       //获取目标类的包名
        String packageName = activityInfo.packageName;

        //获取目标类所在的apk或者jar存放的路径
        String dexPath = activityInfo.applicationInfo.sourceDir;
        //获取目标类dex文件存放在调用者里的路径
        String dexOutputDir = getApplicationInfo().dataDir;
        //获取目标类所使用的C/C++库存放路径
        String nativeLibraryDir = activityInfo.applicationInfo.nativeLibraryDir;
        //获取类装载器
        ClassLoader classLoader = getClassLoader();

        DexClassLoader dcl = new DexClassLoader(dexPath,dexOutputDir,nativeLibraryDir,classLoader);
        try {
            //装载目标类
            Class<?> clazz = dcl.loadClass(packageName + ".Test");
            //获取构造器并实例化对象
            Constructor<?> constructor = clazz.getConstructor();
            Object o = constructor.newInstance();
            //获取成员方法
            Method display = clazz.getMethod("show", String.class);
            display.invoke(o, "grandShow");
        } catch (Exception e) {
            e.printStackTrace();
        }
PathClassLoader :
    // 获取apk或者jar的路径 
    String apkPath = actInfo.applicationInfo.sourceDir;  
    // 获取lib库代码的目录  
    String libPath = actInfo.applicationInfo.nativeLibraryDir;  
  
    PathClassLoader pcl = new PathClassLoader(apkPath, libPath,  
            this.getClassLoader());  
    // 加载类  
    try {  
        Class clazz = pcl.loadClass("com.grandshow.Test");
        Method method = clazz.getMethod("show",String.class);   
        method.invoke(clazz.newInstance(), "grandShow");
    } catch (Exception e) {  
        e.printStackTrace();  
    }

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值