提问人:Labotha 提问时间:1/18/2022 最后编辑:Labotha 更新时间:1/19/2022 访问量:370
AGP 7+ / JDK 11 / 版本:ClassNotFoundException:未找到类“okhttp3。MultipartBody$Part“,路径:DexPathList
AGP 7+ / JDK 11 / release: ClassNotFoundException: Didn't find class "okhttp3.MultipartBody$Part" on path: DexPathList
问:
正如标题所说,自从我们更新到 Java 11 和 AGP 7+ 以来,我在项目上遇到了一些问题。 该问题仅在发布版和我们使用 okhttp3 进行改造调用时发生。多部分主体 :
2022-01-18 00:56:23.043 27908-27908/com.test.okhttpissue E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.okhttpissue, PID: 27908
java.lang.TypeNotPresentException: Type okhttp3.MultipartBody$Part not present
at libcore.reflect.ParameterizedTypeImpl.getRawType(ParameterizedTypeImpl.java:67)
at libcore.reflect.ParameterizedTypeImpl.getResolvedType(ParameterizedTypeImpl.java:76)
at libcore.reflect.GenericArrayTypeImpl.getGenericComponentType(GenericArrayTypeImpl.java:32)
at j2.y.j(:362)
at j2.s$a.j(:812)
at j2.s$a.g(:626)
at j2.s$a.f(:325)
at j2.s$a.b(:206)
at j2.s.b(:67)
at j2.v.b(:26)
at j2.u.c(:202)
at j2.u$a.invoke(:160)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy2.a(Unknown Source)
at f1.a.a(:41)
at com.test.okhttpissue.MainActivity.G(:30)
at com.test.okhttpissue.MainActivity.F(Unknown Source:0)
at f1.b.onClick(Unknown Source:0)
at android.view.View.performClick(View.java:7259)
at android.view.View.performClickInternal(View.java:7236)
at android.view.View.access$3600(View.java:801)
at android.view.View$PerformClick.run(View.java:27896)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
Caused by: java.lang.ClassNotFoundException: okhttp3.MultipartBody$Part
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at libcore.reflect.ParameterizedTypeImpl.getRawType(ParameterizedTypeImpl.java:65)
at libcore.reflect.ParameterizedTypeImpl.getResolvedType(ParameterizedTypeImpl.java:76)
at libcore.reflect.GenericArrayTypeImpl.getGenericComponentType(GenericArrayTypeImpl.java:32)
at j2.y.j(:362)
at j2.s$a.j(:812)
at j2.s$a.g(:626)
at j2.s$a.f(:325)
at j2.s$a.b(:206)
at j2.s.b(:67)
at j2.v.b(:26)
at j2.u.c(:202)
at j2.u$a.invoke(:160)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy2.a(Unknown Source)
at f1.a.a(:41)
at com.test.okhttpissue.MainActivity.G(:30)
at com.test.okhttpissue.MainActivity.F(Unknown Source:0)
at f1.b.onClick(Unknown Source:0)
at android.view.View.performClick(View.java:7259)
at android.view.View.performClickInternal(View.java:7236)
at android.view.View.access$3600(View.java:801)
at android.view.View$PerformClick.run(View.java:27896)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
Caused by: java.lang.ClassNotFoundException: Didn't find class "okhttp3.MultipartBody$Part" on path: DexPathList[[zip file "/data/app/com.test.okhttpissue-pBclZ8Dcl_TuV_j7iAp7oA==/base.apk"],nativeLibraryDirectories=[/data/app/com.test.okhttpissue-pBclZ8Dcl_TuV_j7iAp7oA==/lib/arm64, /system/lib64, /system/product/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at libcore.reflect.ParameterizedTypeImpl.getRawType(ParameterizedTypeImpl.java:65)
at libcore.reflect.ParameterizedTypeImpl.getResolvedType(ParameterizedTypeImpl.java:76)
at libcore.reflect.GenericArrayTypeImpl.getGenericComponentType(GenericArrayTypeImpl.java:32)
at j2.y.j(:362)
at j2.s$a.j(:812)
at j2.s$a.g(:626)
at j2.s$a.f(:325)
at j2.s$a.b(:206)
at j2.s.b(:67)
at j2.v.b(:26)
at j2.u.c(:202)
at j2.u$a.invoke(:160)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy2.a(Unknown Source)
at f1.a.a(:41)
at com.test.okhttpissue.MainActivity.G(:30)
at com.test.okhttpissue.MainActivity.F(Unknown Source:0)
at f1.b.onClick(Unknown Source:0)
at android.view.View.performClick(View.java:7259)
at android.view.View.performClickInternal(View.java:7236)
at android.view.View.access$3600(View.java:801)
at android.view.View$PerformClick.run(View.java:27896)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
2022-01-18 00:56:23.074 27908-27908/com.test.okhttpissue I/Process: Sending signal. PID: 27908 SIG: 9
在 AGP 4.2.2 / Java 1.8 上不会出现此问题。
我能够使用以下配置在基本示例应用程序中重现它:
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.test.okhttpissue"
minSdk 24
targetSdk 29
versionCode 1
versionName "1.0"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
signingConfig signingConfigs.debug
debuggable true
minifyEnabled true
shrinkResources true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "io.reactivex.rxjava3:rxjava:3.1.3"
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
}
以及以下片段:
class IssueDemo {
val testApi: TestApi by lazy {
Retrofit.Builder()
.baseUrl("https://google.com")
.client(OkHttpClient().newBuilder().build())
.addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(TestApi::class.java)
}
interface TestApi {
@Multipart
@POST("test/files")
fun uploadMultipleFiles(@Part files: Array<MultipartBody.Part?>): Single<String>
}
fun execute() {
val file = File("")
val requestFile: RequestBody =
RequestBody.create(MediaType.parse("multipart/form-data"), file)
val test = MultipartBody.Part.createFormData("nameFormData", file.name, requestFile)
testApi.uploadMultipleFiles(arrayOf(test))
}
}
我尝试了很多方法,但到目前为止,似乎唯一可以解决它的方法是添加一个 proguard 规则,但感觉不对。在 AGP 4.2.2 中,它已经使用了 R8 和与库捆绑在一起的 proguard 规则,那么为什么我们突然需要另一个特定的规则来针对这个库的一个类呢?-keep class okhttp3.MultipartBody
编辑:似乎在不触及任何 proguard 规则的情况下从 切换到 ,可以解决问题。有人知道可能会发生什么吗?Array<MultipartBody.Part?>
List<MultipartBody.Part?>
答:
0赞
Don Ha
1/18/2022
#1
R8 可能无法检测到正在使用的类,因为它可能由反射调用。如果是这种情况,您必须在 proguard-project.txt 中添加显式保留规则。
评论
0赞
Labotha
1/19/2022
它确实适用于该规则,但在使用 AGP 4.2.2 时没有必要,AGP 4.2.2 也使用 R8。而且这个被混淆的类以前没有引起任何问题。-keep class okhttp3.MultipartBody
评论