将Guava导入Android项目的正确方法是什么?每当我尝试使用它时,我都会得到NoClassDefFoundError
。
这就是我正在做的事情来产生崩溃。我正在使用Android Studio 3.0 Canary 7。
File > New > New Project
模板创建新项目API 26.0
,定位Empty Activity
。在app/build.gradle
部分
dependencies
implementation "com.google.guava:guava:20.0"
将其添加到MainActivity.java
ImmutableList<String> foo = ImmutableList.of("A", "B", "C");
Log.d("MainActivity", foo.get(0));
运行应用程序并打开Logcat以查看此异常:
FATAL EXCEPTION: main
Process: com.letsdoit.guavaissue, PID: 14366
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/common/collect/ImmutableList;
at com.letsdoit.guavaissue.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.common.collect.ImmutableList" on path: DexPathList[[zip file "/data/app/com.letsdoit.guavaissue-1/base.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.letsdoit.guavaissue-1/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.letsdoit.guavaissue.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我几乎可以肯定这与Gauva很大并且不能很好地使用multidex有关,但我不知道该怎么做。这些是我试图无济于事的一些值得注意的事情:
启用multidex并在multiDexKeepFile中指定ImmutableList。
禁用即时运行。
从设备中拉出APK并验证了Guava课程在APK中。
按照此堆栈中的建议溢出question。
答案 0 :(得分:0)
<强> TL; DR 强>
使用番石榴版22.0-android
及以上。确保使用-android
风格,否则您将遇到NoClassDefFoundError
。
<强>解释强>
我在发布问题之后了解了如何手动清理项目并从模拟器中卸载apks。事实证明版本20.0
确实有用,但我之前尝试过版本21.0
并且无法清理。
版本-android
的非21.0
版本的guava正在使用Java 8. 21.0
之前的android风格和版本使用Java 7.这些在{{3}中有所描述对于版本22.0。
我测试了这些口味和版本:
20.0 (Java 7)
- 作品21.0 (Java 8)
- 没有工作22.0 (Java 8)
- 没有工作22.0-android (Java 7)
- 作品使用版本21.0
或22.0
(无-android
)时,ImmutableList
类被引用但未编译到dex文件中(因为它已经在斜体)。这导致了NoClassDefFoundError
。
作为android APK with dangling references to ImmutableList解释
在树视图中,斜体节点是没有的参考 选定DEX文件中的定义。
它进一步解释了
DEX文件可以引用在a中定义的方法和字段 不同的文件。例如,System.out.println()是对它的引用 Android框架中的println()方法。
但是在这种情况下,没有其他文件可以告诉这些方法和类定义。它只是无法添加它们。
与使用20.0
或22.0-android
进行对比,其中实际上编译了ImmutableList类。
该应用程序按预期启动。