① Tinker loader classes are found in old secondary dex 错误 和②groovy.lang.MissingPropertyException: Co

本文解决Tinker在使用ButterKnife 8.5以上版本时的两个常见错误:Tinkerloaderclasses在旧次dex中找不到及groovy.lang.MissingPropertyException异常。通过调整Gradle配置,删除过时插件应用,并正确设置annotationProcessor,最终解决了多dex环境下的兼容性问题。

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

① Tinker loader classes are found in old secondary dex 错误 和②groovy.lang.MissingPropertyException: Could not get unknown property ‘packageForR’ for task 错误

②错误网上一堆的butterknife 降级的办法,但更有可能的是,你用了butterknife 8.5以上的版本,但又在app的build.gradle里添加了apply plugin: ‘com.jakewharton.butterknife’
这个是8.5以下版本的做法。在gradle 3.0.1 的时候不报错,但gradle 3.2.0之后,就会报错 butterknife 8.5 以后的版本,只要是引用是有注解处理器的annotationProcessor ,比如类似
implementation 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'就删掉apply plugin: ‘com.jakewharton.butterknife’

①错误一开始是tinker 死活打补丁包不成功,各种研究。升级gradle 到3.2.0,gradle.properties 又需要加
#gradle 3.2.0 需要添加 android.enableD8.desugaring= true #gradle 3.2.0 需要添加 android.useDexArchive= true
来支持,结果support包冲突,因为3.2.0 自带的databingding中用的support包26.1.0 ,结果又在manifest指定 <meta-data tools:replace="android:value" android:name="android.support.VERSION" android:value="26.0.2" />
xmlns:tools="http://schemas.android.com/tools"

这时候出现②错误,看提示似乎是gradle 升级到3.2.0之后,tinker相关的引导加载类,被分包在了非main dex 中,失去了主导权, 于是在app 的gradle 中手动添加 multiDexKeepProguard file(‘tinker_multidexkeep.pro’) , tinker_multidexkeep.pro文件在tinker生成的build文件中有。终于问题解决。我现在怎么感觉原生的坑越来越多。

<think>好的,用户遇到了个SecurityException,错误信息是“Writabledex file'/data/data/com.example.kucun2/code_cache/.overlay/base.apk/classes7.dex'is notallowed.”。我需要先理解这个问题的原因。首先,Dex文件是Android应用的字节码文件,通常在应用安装时由系统处理。用户提到的路径中有code_cache.overlay目录,这可能涉及到动态加载Dex文件的情况。SecurityException通常与权限有关,尤其是在尝试写入或访问不允许的文件位置时。接下来,我需要考虑可能的触发场景。比如,用户可能在应用运行时动态生成或修改Dex文件,或者使用了某些热修复或插件化框架,这些框架可能会尝试在应用的私有目录中写入Dex文件。但根据Android的安全策略,某些目录可能不允许直接写入Dex文件,尤其是在Android10及以上版本中,对文件访问的限制更加严格。然后,我需要回忆相关的Android权限目录访问规则。应用的私有目录通常是/data/data/包名/,其中cache目录(如code_cache)通常是可以写入的,但某些子目录可能需要特定权限或正确的访问方式。另外,Android不允许直接从私有目录加载Dex文件,除非使用正确的API,如DexClassLoader,并且路径设置正确。可能的原因包括:1.尝试在非允许的目录中写入或加载Dex文件。 2.使用了错误的类加载器,或者路径配置不正确。 3.目标目录的权限设置不正确,导致无法写入或访问。接下来,我需要寻找解决方案。可能的解决步骤包括: -检查代码中动态加载Dex的部分,确保使用DexClassLoader而不是原生的DexFile.openDexFile。-确认写入Dex文件的目录是否符合Android的要求,比如使用getCodeCacheDir()获取正确的目录。-检查是否在AndroidManifest.xml中声明了必要的权限,比如WRITE_EXTERNAL_STORAGE,尽管在较新版本中可能不需要。-确保目标目录存在,并且在写入前创建了必要的父目录。-如果使用了热修复库,可能需要更新库版本或检查其兼容性。此外,还需要考虑Android版本的问题,因为不同版本对文件系统的权限管理可能不同。例如,Android10及以上版本引入了作用域存储,限制了应用对文件的访问。最后,需要提供具体的代码示例,说明如何正确配置DexClassLoader目录路径,并解释每步的作用,确保用户能够正确修改代码以避免该异常。</think>### **解决方案** #### **问题分析** 错误 `SecurityException: Writable dex file ... is not allowed` 通常发生在 Android 应用尝试动态加载或写入 Dex 文件到受限制的目录时。从 Android 10(API 29)开始,系统加强了对应用私有目录的访问限制,禁止直接写入或加载 Dex 文件到某些路径(如 `code_cache/.overlay`)。 --- ### **方法 1:使用合法的 Dex 文件目录** Android 要求动态加载的 Dex 文件必须存储在应用特定的目录中(如 `code_cache` 或 `files`)。使用 `Context.getCodeCacheDir()` 或 `Context.getFilesDir()` 获取合法路径。 ```java // 示例代码:动态加载 Dex 文件 File dexDir = new File(getCodeCacheDir(), "dynamic_dex"); if (!dexDir.exists()) { dexDir.mkdirs(); // 确保目录存在 } // 使用 DexClassLoader 加载 Dex 文件 DexClassLoader dexClassLoader = new DexClassLoader( dexFilePath, // Dex 文件源路径(如 APK 或 JAR) dexDir.getAbsolutePath(), // 目标目录(必须可写) null, // 父 ClassLoader getClassLoader() // 当前 ClassLoader ); ``` #### **解释** - `getCodeCacheDir()` 是系统允许写入临时代码文件的目录。 - `DexClassLoader` 是 Android 官方提供的动态加载 Dex 文件的类,需指定合法的目标目录。 --- ### **方法 2:检查目标目录权限** 确保目标目录的路径权限符合 Android 要求: 1. **不要硬编码路径**:避免直接使用 `/data/data/...`,而是通过 `Context` 方法获取路径。 2. **避免使用 `.overlay` 目录**:此目录可能被系统保留,不允许直接操作。 #### **错误代码示例(需避免)** ```java // 错误:直接使用 code_cache/.overlay 路径 File badDir = new File(getCodeCacheDir(), ".overlay/base.apk"); DexFile.openDexFile(badDir.getAbsolutePath()); // 触发 SecurityException ``` --- ### **方法 3:适配 Android 10+ 的作用域存储** 如果应用目标 SDK ≥ 29(Android 10+),需遵守作用域存储规则: 1. **禁用旧版动态加载**(如果可能):某些热修复框架(如 Tinker)可能需要更新到兼容版本。 2. **在 `AndroidManifest.xml` 中添加权限**(仅限必要情况): ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" /> <!-- 仅对 Android 9 及以下生效 --> ``` --- ### **方法 4:检查热修复框架配置** 如果使用了热修复框架(如 Tinker、Sophix),需确保其配置正确: 1. **更新框架版本**:旧版本可能不兼容 Android 10+。 2. **检查补丁文件路径**: ```gradle // Tinker 配置示例(build.gradle) tinkerPatch { dex { loader = ["com.example.kucun2.MyTinkerApplication"] // 指定合法的类加载器 dexMode = "jar" // 使用 JAR 格式代替直接写入 Dex } } ``` --- ### **错误原因总结** - **直接操作受限制目录**:尝试写入或加载 Dex 文件到系统保留路径(如 `code_cache/.overlay`)。 - **未使用合法的类加载器**:直接调用 `DexFile.openDexFile()` 而非通过 `DexClassLoader`。 - **目标 SDK 版本兼容性问题**:Android 10+ 加强了目录访问限制。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值