В одной из наших сборок выпуска мы используем ProGuard , где это помогает запутывать и минимизировать код. Эта проблема не воспроизводится на моем устройстве или эмуляторе, но от некоторых пользователей через Crashlytics мы получаем исключение, которое говорит, что система не может найти класс. Исключение составляют различные устройства и выше Android Lollipop. (API 21)
Трассировка исключений:
Caused by java.lang.ClassNotFoundException: Did not find class "com.example.android.views.CustomImageView" on path: DexPathList[[zip file "/data/app/com.example.android-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.android-1/lib/arm, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass + 56(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass + 511(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass + 469(ClassLoader.java:469)
at android.view.LayoutInflater.createView + 583(LayoutInflater.java:583)
at android.view.LayoutInflater.createViewFromTag + 764(LayoutInflater.java:764)
at android.view.LayoutInflater.createViewFromTag + 704(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate + 835(LayoutInflater.java:835)
at android.view.LayoutInflater.rInflateChildren + 798(LayoutInflater.java:798)
at android.view.LayoutInflater.rInflate + 838(LayoutInflater.java:838)
at android.view.LayoutInflater.rInflateChildren + 798(LayoutInflater.java:798)
at android.view.LayoutInflater.rInflate + 838(LayoutInflater.java:838)
at android.view.LayoutInflater.rInflateChildren + 798(LayoutInflater.java:798)
at android.view.LayoutInflater.inflate + 515(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate + 423(LayoutInflater.java:423)
at com.example.android.fragments.MyFragment.onCreateView + 160(AdPopupFragmentVertical.java:160)
at androidx.fragment.app.Fragment.performCreateView + 2600(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState + 881(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState + 1238(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState + 1303(FragmentManagerImpl.java:1303)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange + 2659(FragmentManagerImpl.java:2659)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated + 2613(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated + 246(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart + 542(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart + 201(AppCompatActivity.java:201)
Связанное правило ProGuard:
-keep class com.example.android.views.** { *; }
И, чтобы go еще безопаснее, Я также добавил аннотацию @Keep
в начало класса, например:
package com.example.android.views;
import androidx.annotation.Keep;
@Keep
public class CustomImageView extends AppCompatImageView {
// rest of the code
}
Чтобы убедиться, что я создал релиз APK и проверил его с помощью APK Analyzer. Теперь приложение использует MultiDex (поскольку оно должно содержать рекламу), а файл classes.dex
содержит представление с его правильным именем, путем (я имею в виду пакет) и методами. Итак, я не понимаю, почему некоторые устройства не могут найти это представление.
Что еще можно сделать, чтобы решить эту проблему? Спасибо за любую помощь, спасибо.
Редактировать: Если это помогает, это представление является специальным представлением, которое создает тень в зависимости от растрового изображения, в которое она отправляется с использованием Renderscript выше Android Lollipop. (API 21)
Редактировать 2: Вот мой файл build.gradle уровня приложения. (пропущены ненужные части)
android {
compileSdkVersion 29
buildToolsVersion '28.0.3' // this is ignored already
defaultConfig {
applicationId "com.example.android"
minSdkVersion 16
targetSdkVersion 29
versionCode 1000
versionName "1000"
multiDexEnabled true
lintOptions {
checkReleaseBuilds false
}
vectorDrawables.useSupportLibrary = true
}
dexOptions {
preDexLibraries = false
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.release
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
applicationVariants.all { variant ->
def flavor = variant.mergedFlavor
def name = flavor.getVersionName()
if (variant.buildType.isDebuggable())
name += 'd'
else
name += 'r'
variant.outputs.each { output ->
output.versionNameOverride = name
}
variant.outputs.all {
def versionName = variant.versionName
versionName += variant.buildType.isDebuggable() ? 'd' : 'r'
outputFileName = "example-${versionName}.apk"
}
}
useLibrary 'org.apache.http.legacy'
}