You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android应用中使用Class.forName()加载系统分区的Java类?

Android运行时加载外部类及AOSP系统集成方案

一、Android应用运行时动态加载外部Jar(非系统分区场景)

Android不支持传统Java的-cp参数指定类路径,需通过DexClassLoader实现动态加载,步骤如下:

  1. 准备Jar文件:确保ThatClass.jar包含com.example.ThatClass类,无需提前转dex(DexClassLoader会自动优化生成dex文件)。
  2. 放置Jar到可访问路径:将Jar放到应用私有目录(如内部存储的files文件夹),避免权限问题:
    // 示例:从assets复制Jar到内部存储
    InputStream is = getAssets().open("ThatClass.jar");
    File jarFile = new File(getFilesDir(), "ThatClass.jar");
    FileOutputStream fos = new FileOutputStream(jarFile);
    byte[] buffer = new byte[1024];
    int len;
    while ((len = is.read(buffer)) != -1) {
        fos.write(buffer, 0, len);
    }
    is.close();
    fos.close();
    
  3. 使用DexClassLoader加载类:
    // 初始化类加载器:参数分别为Jar路径、优化dex输出目录、依赖库路径、父类加载器
    DexClassLoader classLoader = new DexClassLoader(
        jarFile.getAbsolutePath(),
        getCacheDir().getAbsolutePath(),
        null,
        getClassLoader()
    );
    
    try {
        // 加载目标类
        Class<?> thatClass = classLoader.loadClass("com.example.ThatClass");
        // 反射创建实例并调用方法
        Object instance = thatClass.getDeclaredConstructor().newInstance();
        Method targetMethod = thatClass.getMethod("yourMethodName");
        targetMethod.invoke(instance);
    } catch (Exception e) {
        e.printStackTrace();
    }
    

注意:若将Jar放在外部存储,需申请对应读写权限(Android 10+建议使用应用专属外部目录)。

二、AOSP构建时将Jar纳入系统分区的方案

若要把ThatClass.jar作为系统库放入系统分区,有以下3种可行方案:

方案1:整合到Framework层

将Jar作为Framework的静态库,所有应用可直接访问:

  1. 将ThatClass.jar复制到AOSP源码的frameworks/base/libs/目录。
  2. 修改frameworks/base/Android.mk,添加Jar模块定义:
    include $(CLEAR_VARS)
    LOCAL_MODULE := ThatClassLib
    LOCAL_MODULE_TAGS := optional
    LOCAL_SRC_FILES := libs/ThatClass.jar
    LOCAL_MODULE_CLASS := JAVA_LIBRARIES
    LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
    include $(BUILD_PREBUILT)
    
  3. 在Framework主模块中引用该库:
    # 在frameworks/base/Android.mk的LOCAL_STATIC_JAVA_LIBRARIES中添加
    LOCAL_STATIC_JAVA_LIBRARIES += ThatClassLib
    
  4. 重新编译Framework并刷入系统,应用可直接通过Class.forName("com.example.ThatClass")加载类。

方案2:独立系统库模块

将Jar打包为独立的系统库,可灵活控制是否预装:

  1. 在AOSP源码中创建独立模块目录(如packages/services/ThatClassLib/),放入ThatClass.jar和Android.mk:
    include $(CLEAR_VARS)
    LOCAL_MODULE := ThatClassLib
    LOCAL_MODULE_TAGS := optional
    LOCAL_SRC_FILES := ThatClass.jar
    LOCAL_MODULE_CLASS := JAVA_LIBRARIES
    LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
    LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES) # 指定输出到system/framework
    include $(BUILD_PREBUILT)
    
  2. 在设备配置文件(如device/<厂商>/<设备>/device.mk)中添加预装配置:
    PRODUCT_PACKAGES += ThatClassLib
    
  3. 编译系统后,Jar会被放到/system/framework/目录。普通应用可通过系统类加载器加载:
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    Class<?> thatClass = systemClassLoader.loadClass("com.example.ThatClass");
    
    若需让应用直接访问,可给应用添加系统签名并设置android:sharedUserId="android.uid.system"。

方案3:加入BootClasspath

将Jar纳入系统核心类路径,让所有应用默认可访问:

  1. 修改AOSP源码的build/core/config.mk,在BOOTCLASSPATH中添加Jar路径:
    BOOTCLASSPATH += $(TARGET_OUT_JAVA_LIBRARIES)/ThatClassLib.jar
    
  2. 重新编译整个系统,此时com.example.ThatClass会像系统核心类一样,被所有应用的类加载器自动识别,无需额外代码即可通过Class.forName加载。

内容的提问来源于stack exchange,提问作者DarkSoda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:52:09