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

Android 14设备上Razorpay AAR动态代码加载SecurityException问题求助

问题描述

以下是初始化Razorpay支付的代码片段:

public void setPayment(PaymentResponse response){        
    this.response = response;        
    layout.findViewById(R.id.loader).setVisibility(View.GONE);        
    layout.findViewById(R.id.payment_area).setVisibility(View.VISIBLE);        
    if(razorpay==null){            
        // 错误源于引用本地aar文件
        razorpay = new Razorpay(getActivity(),response.getPayment().getGatewayKey());        
    }        
    razorpay.setWebView(paymentLayout.findViewById(R.id.payments));        
    // 后续代码省略    
}

在Android 14设备上运行时触发如下错误:

java.lang.SecurityException: writable dex file '/data/user/io.project.package.name/cache/. ' is not allowed.

环境信息

  • 本地libs目录存放razorpay.aar,build.gradle依赖配置:
    implementation fileTree(dir: 'libs', include: ['*.aar'])
    implementation files('libs/razorpay.aar')
    
  • 仅Android 14设备出现该问题,低版本系统运行正常
  • 已知升级Razorpay AAR可解决问题,但涉及大量代码重构及服务端改动,需寻求无需升级AAR的应用层热修复方案
  • 编译环境:Android Studio Iguana | 2023.2.1 Patch 1
无需升级AAR的修复方案

方案1:临时禁用Dex优化(应急热修复)

在AndroidManifest.xml的<application>标签中添加以下属性,强制系统不优化内嵌Dex,避免旧版Razorpay的Dex写入操作触发安全限制:

android:extractNativeLibs="true"
android:useEmbeddedDex="false"

⚠️ 注意:该方案可能影响应用运行性能,仅作为临时修复使用,后续仍需规划升级AAR。

方案2:重定向临时目录到系统允许的路径

Android 14禁止在应用缓存目录加载可写Dex文件,旧版Razorpay恰好在此目录写入临时Dex。可通过自定义Application类,将系统临时目录重定向到code_cache(Android 14允许加载Dex的目录):

  1. 自定义Application类:
public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        File codeCacheDir = getCodeCacheDir();
        if (codeCacheDir != null) {
            // 将系统临时目录替换为code_cache
            System.setProperty("java.io.tmpdir", codeCacheDir.getAbsolutePath());
        }
    }
}
  1. 在AndroidManifest.xml中指定该Application:
<application
    android:name=".MyApp"
    <!-- 其他原有属性 -->
    >
    <!-- 其他组件配置 -->
</application>

方案3:反射修改Razorpay的缓存路径

如果上述方案无效,可尝试通过反射修改Razorpay内部使用的缓存目录,指向code_cache:

// 必须在初始化Razorpay实例之前执行这段代码
try {
    // 替换为旧版Razorpay中实际处理缓存的类名
    Class<?> razorpayClass = Class.forName("com.razorpay.Razorpay");
    // 替换为该类中存储缓存目录的字段名
    Field cacheDirField = razorpayClass.getDeclaredField("cacheDir");
    cacheDirField.setAccessible(true);
    // 设置为系统允许的code_cache目录
    File allowedDir = getActivity().getCodeCacheDir();
    cacheDirField.set(null, allowedDir);
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace();
}

⚠️ 注意:需根据旧版Razorpay AAR的内部结构调整反射的类名和字段名,建议反编译本地AAR确认具体结构后再使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:20:03