android - 在 Android Pre L 设备上使用带有 jack 编译器的 Java 8

标签 android java-8 android-5.0-lollipop android-4.4-kitkat

我目前正在更新我的应用程序以使用 java 8。因此我正在使用 jack 编译器。

这适用于每台搭载 Android 5.0 或更高版本的设备。在具有 Pre Lollipop 版本的旧设备上,我遇到以下异常:

Caused by: java.lang.ClassNotFoundException: Didn't find class "de.gelbeseiten.android.GelbeSeitenApplication" on path: DexPathList[[zip file "/data/app/de.gelbeseiten.android-1.apk"],nativeLibraryDirectories=[/data/app-lib/de.gelbeseiten.android-1, /vendor/lib, /system/lib, /system/lib/arm]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:497) at java.lang.ClassLoader.loadClass(ClassLoader.java:457) at android.app.Instrumentation.newApplication(Instrumentation.java:981) at android.app.LoadedApk.makeApplication(LoadedApk.java:511) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4722)  at android.app.ActivityThread.access$1600(ActivityThread.java:172)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:146)  at android.app.ActivityThread.main(ActivityThread.java:5653)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)

我 99% 确定,对 Java 8 的更改是造成这种情况的原因,因为如果我查看当前的公共(public)版本并且除了包含 Java 8 之外没有进行任何更改,就会发生这种情况。

不幸的是,我在谷歌中找不到任何关于这个的东西。在 java 8 支持的 google android 站点上,没有关于所需的最低 android 版本的任何内容。 https://developer.android.com/guide/platform/j8-jack.html

我不认为完整的 build.gradle 文件有用,但这里有一个 fragment :

android {
    useLibrary 'org.apache.http.legacy'

    defaultConfig {
        [...]
        multiDexEnabled = true
        jackOptions {
            enabled true
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/dependencies.txt'
        exclude 'META-INF/LGPL2.1'
    }
}

我从来没有手动更改过 proguard-rules.txt,但这里是:

# Add project specific ProGuard rules here.
# By teilnehmer, the flags in this file are appended to flags     specified
# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

##---------------Begin: proguard configuration common for all Android apps ----------
-dontobfuscate
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations             !code/simplification/arithmetic,!field/*,!class/merging/*

-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses
-libraryjars libs

# The official support library.
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }

# Library JARs.
-keep class de.greenrobot.dao.** { *; }
-keep interface de.greenrobot.dao.** { *; }
-keep class org.joda.** { *; }
-keep interface org.joda.** { *; }
-keep class com.loopj.android.http.** { *; }
-keep interface com.loopj.android.http.** { *; }

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService

# Espress: java.lang.NoSuchMethodError:     android.support.test.espresso.Espresso
-keep class android.support.v7.widget.RecyclerView { *; }

# adjust
-keep class com.adjust.sdk.** { *; }
-keep class com.google.android.gms.common.** { *; }
-keep class com.google.android.gms.ads.identifier.** { *; }

-keep class com.adjust.sdk.plugin.MacAddressUtil {
    java.lang.String getMacAddress(android.content.Context);
}
-keep class com.adjust.sdk.plugin.AndroidIdUtil {
    java.lang.String getAndroidId(android.content.Context);
}
-keep class com.google.android.gms.common.ConnectionResult {
    int SUCCESS;
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient {
    com.google.android.gms.ads.identifier.AdvertisingIdClient$Info getAdvertisingIdInfo (android.content.Context);
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info {
    java.lang.String getId ();
    boolean isLimitAdTrackingEnabled();
}

#keep all classes that might be used in XML layouts
-keep public class * extends android.view.View
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.Fragment

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}


-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}


-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

# Preserve static fields of inner classes of R classes that might be     accessed
# through introspection.
-keepclassmembers class **.R$* {
public static <fields>;
}

# Preserve the special static methods that are required in all     enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep public class * {
public protected *;
}

-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------

##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by teilnehmer, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }

##---------------End: proguard configuration for Gson ----------

Stackoverflow 将部分文件显示为注释,但在我的 Android Studio proguard 文件中并非如此。

Soo...有人有关于此主题的更多信息吗?或者甚至可能修复让应用程序也能在 Pre L 设备上运行?

提前致谢!

最佳答案

首先,如果您正在使用 Instant Run,请将其禁用。目前不适用于 Java 8。

此外,您应该添加:

-keep class de.gelbeseiten.android.** { *; }

还要确保 de.gelbeseiten.android.GelbeSeitenApplication 在您的主 dex 文件中(可能是 classes.dex)。

如果这里没有,你应该这样做:

android {
    buildTypes {
        debug {
            ...
            multiDexEnabled true
            multiDexKeepFile file('multidex_keep_file.txt')
        }
    }
}

并且在您的 multidex_keep_file.txt 中,您需要指定哪些类将出现在您的主 dex 中。

 de/gelbeseiten/android/GelbeSeitenApplication.class
 de/gelbeseiten/android/MainActivity.class (for example)

This text file that specifies additional classes that will be compiled into the main dex file.

Classes specified in the file are appended to the main dex classes computed using aapt.

If set, the file should contain one class per line, in the following format: com/example/MyClass.class

关于android - 在 Android Pre L 设备上使用带有 jack 编译器的 Java 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41220721/

相关文章:

java - lambda 表达式中的错误返回类型

android - Lollipop : making my activity stay in the task that launched the share intent

android - 在 Android 5.0 Lollipop 上不支持 calendarViewShown

android - 如何检查edittext的文本是否为电子邮件地址?

Android - 无法调用 ViewModel 中定义的方法

java - "Clear Memory"+ appWidget 崩溃后服务不重启

java - 无法执行目标 org.jibx :maven-jibx-plugin:1. 2.6 :bind when upgrading from Java 1. 6 到 1.8

java-8 - 如何使用Java 8中的流API通过同一类的不同对象填充数组列表?

android - FAB 和 ListView 的快速返回模式

java - 单击监听器未在 ListFragment 中调用