如何将Guava导入Android应用程序

时间:2018-01-19 01:52:53

标签: android android-studio apk guava

将Guava导入Android项目的正确方法是什么?每当我尝试使用它时,我都会得到NoClassDefFoundError

这就是我正在做的事情来产生崩溃。我正在使用Android Studio 3.0 Canary 7。

  1. 使用File > New > New Project模板创建新项目API 26.0,定位Empty Activity
  2. app/build.gradle部分

    中添加到dependencies
    implementation "com.google.guava:guava:20.0"
    
  3. 将其添加到MainActivity.java

    中的onCreate方法
    ImmutableList<String> foo = ImmutableList.of("A", "B", "C");
    Log.d("MainActivity", foo.get(0));
    
  4. 运行应用程序并打开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)
    
  5. 我几乎可以肯定这与Gauva很大并且不能很好地使用multidex有关,但我不知道该怎么做。这些是我试图无济于事的一些值得注意的事情:

    1. 启用multidex并在multiDexKeepFile中指定ImmutableList。

    2. 禁用即时运行。

    3. 从设备中拉出APK并验证了Guava课程在APK中。

    4. 按照此堆栈中的建议溢出question

1 个答案:

答案 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.022.0(无-android)时,ImmutableList类被引用但未编译到dex文件中(因为它已经在斜体)。这导致了NoClassDefFoundError

release notes

作为android APK with dangling references to ImmutableList解释

  

在树视图中,斜体节点是没有的参考   选定DEX文件中的定义。

它进一步解释了

  

DEX文件可以引用在a中定义的方法和字段   不同的文件。例如,System.out.println()是对它的引用   Android框架中的println()方法。

但是在这种情况下,没有其他文件可以告诉这些方法和类定义。它只是无法添加它们。

与使用20.022.0-android进行对比,其中实际上编译了ImmutableList类。

developer docs

该应用程序按预期启动。