3

由于我升级了 Android Studio,我有点被迫将 Gradle 的版本、buildToolsVersion 和 java 的版本升级到 7。

我的问题是我实际上可以完美地在 Android Lollipop 上运行该项目,但是我失去了向后兼容性,我无法在 API 21 之前的设备上运行应用程序。

Android Studio 版本: 1.0.2
Gradle Wrapper 版本: gradle-2.2.1-all

我遵循了使用 Gradle指南为 Multidex 配置您的应用程序的每一步。

TL;DR代码编译完美,在 Android Lollipop 上运行,不运行之前的 Lollipop。

apply plugin: 'com.android.application'

android {

    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId 'com.mundodescuento'
        minSdkVersion 14
        targetSdkVersion 21
        multiDexEnabled true
    }

    buildTypes {

        release {
            proguardFile('proguard-rules.pro')
            signingConfig signingConfigs.MundoDescuento
            debuggable false
            jniDebuggable false
            renderscriptDebuggable false
            minifyEnabled false
            zipAlignEnabled true
        }

        debug {
            proguardFile('proguard-rules.pro')
            debuggable true
            jniDebuggable true
            renderscriptDebuggable true
            minifyEnabled false
            zipAlignEnabled false
        }
    }
    dexOptions {
        incremental true
        javaMaxHeapSize "4g"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

正如 Dependency 也声明的那样

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:multidex:1.0.0'
}

项目的根依赖项。

dependencies {
    classpath 'com.android.tools.build:gradle:1.0.1'
}

我的应用程序类根据要求扩展了 MultiDexApplication。

public class MundoDescuentoApplication extends MultiDexApplication {
    ...
}

我在 Android 4.0.3 设备上运行项目时得到的堆栈跟踪:

java.lang.ExceptionInInitializerError
            at java.lang.Class.newInstanceImpl(Native Method)
            at java.lang.Class.newInstance(Class.java:1319)
            at android.app.Instrumentation.newApplication(Instrumentation.java:957)
            at android.app.Instrumentation.newApplication(Instrumentation.java:942)
            at android.app.LoadedApk.makeApplication(LoadedApk.java:477)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3938)
            at android.app.ActivityThread.access$1300(ActivityThread.java:123)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4424)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NoClassDefFoundError: com/mundodescuento/model/request_params/LoginForm
            at java.lang.Class.getDeclaredMethods(Native Method)
            at java.lang.Class.getDeclaredMethods(Class.java:703)
            at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:662)
            at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:356)
            at com.google.inject.internal.ConstructorBindingImpl.getInternalDependencies(ConstructorBindingImpl.java:151)
            at com.google.inject.internal.InjectorImpl.getInternalDependencies(InjectorImpl.java:585)
            at com.google.inject.internal.InjectorImpl.cleanup(InjectorImpl.java:543)
            at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:529)
            at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:847)
            at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:772)
            at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:256)
            at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:205)
            at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:853)
            at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
            at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
            at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:133)
            at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
            at com.google.inject.Guice.createInjector(Guice.java:95)
            at com.google.inject.Guice.createInjector(Guice.java:72)
            at com.google.inject.Guice.createInjector(Guice.java:62)
            at com.mundodescuento.MundoDescuentoApplication.<clinit>(MundoDescuentoApplication.java:22)
            at java.lang.Class.newInstanceImpl(Native Method)
            at java.lang.Class.newInstance(Class.java:1319)
            at android.app.Instrumentation.newApplication(Instrumentation.java:957)
            at android.app.Instrumentation.newApplication(Instrumentation.java:942)
            at android.app.LoadedApk.makeApplication(LoadedApk.java:477)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3938)
            at android.app.ActivityThread.access$1300(ActivityThread.java:123)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4424)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.ClassNotFoundException: com.mundodescuento.model.request_params.LoginForm
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
            at java.lang.Class.getDeclaredMethods(Native Method)
            at java.lang.Class.getDeclaredMethods(Class.java:703)
            at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:662)
            at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:356)
            at com.google.inject.internal.ConstructorBindingImpl.getInternalDependencies(ConstructorBindingImpl.java:151)
            at com.google.inject.internal.InjectorImpl.getInternalDependencies(InjectorImpl.java:585)
            at com.google.inject.internal.InjectorImpl.cleanup(InjectorImpl.java:543)
            at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:529)
            at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:847)
            at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:772)
            at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:256)
            at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:205)
            at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:853)
            at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
            at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
            at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:133)
            at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
            at com.google.inject.Guice.createInjector(Guice.java:95)
            at com.google.inject.Guice.createInjector(Guice.java:72)
            at com.google.inject.Guice.createInjector(Guice.java:62)
            at com.mundodescuento.MundoDescuentoApplication.<clinit>(MundoDescuentoApplication.java:22)
            at java.lang.Class.newInstanceImpl(Native Method)
            at java.lang.Class.newInstance(Class.java:1319)
            at android.app.Instrumentation.newApplication(Instrumentation.java:957)
            at android.app.Instrumentation.newApplication(Instrumentation.java:942)
            at android.app.LoadedApk.makeApplication(LoadedApk.java:477)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3938)
            at android.app.ActivityThread.access$1300(ActivityThread.java:123)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4424)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
            at dalvik.system.NativeStart.main(Native Method)

编辑 02/10/15:添加了 MundoDescuentoApplication.java 和 LoginForm.java

堆栈跟踪中出现的类中的行是private static final Injector injector = Guice.createInjector(new ApplicationGuiceModule(), new GsonModule());

package com.mundodescuento;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.multidex.MultiDexApplication;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.mundodescuento.module.ApplicationGuiceModule;
import com.mundodescuento.module.GsonModule;
import com.parse.Parse;
import com.parse.ParseFacebookUtils;

/**
 * Created by gmuniz on 6/30/14.
 */
public class MundoDescuentoApplication extends MultiDexApplication {

    private static MundoDescuentoApplication mInstance;
    private static final String SHARED_PREFFERENCES = "com.mundodescuento.Prefferences";
    private static final Injector injector = Guice.createInjector(new ApplicationGuiceModule(), new GsonModule());

    private static SharedPreferences sharedPreferences;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;

        Parse.initialize( ... );
        ParseFacebookUtils.initialize(getString(R.string.facebook_app_id));

        sharedPreferences = getSharedPreferences(SHARED_PREFFERENCES, Context.MODE_PRIVATE);
    }

    /**
     * Retrieves an instance from the {@link SharedPreferences}
     *
     * @return
     */
    public static SharedPreferences getSharedPreferences() {
        return MundoDescuentoApplication.sharedPreferences;
    }

    /**
     * This is a convenience for {@link com.google.inject.Injector#injectMembers(Object) Injector.injectMembers(Object object)}
     */
    public static void injectMembers(final Object object) {
        injector.injectMembers(object);
    }

    /**
     * Retrieve the application in a static way.
     *
     * @return the context.
     */
    public static Context getAppContext() {
        return mInstance;
    }
}

LoginForm.java

package com.mundodescuento.model.request_params;

/**
 * Created by gmuniz on 2/4/15.
 */
public class LoginForm {

    private final String email;
    private final String password;

    private LoginForm(final Builder builder) {
        this.email = builder.email;
        this.password = builder.password;
    }

    public static class Builder {
        private String email;
        private String password;

        public Builder email(final String email) {
            this.email = email;

            return this;
        }

        public Builder password(final String password) {
            this.password = password;

            return this;
        }

        public LoginForm build() {
            return new LoginForm(this);
        }
    }

    public String getEmail() {
        return email;
    }

    public String getPassword() {
        return password;
    }

}

我已经失去了这方面的所有线索,任何帮助将不胜感激!

4

3 回答 3

2

对我来说,问题是通过改变和添加一些东西来解决的。首先需要通过添加启用multidex

defaultConfig {
    multiDexEnabled true
}

然后添加此依赖项

dependencies {
    compile 'com.google.inject:guice:4.0-beta5:no_aop'
    compile 'com.android.support:multidex:1.0.0'  
}

清单应用程序的变化

<application
    ...
    android:name="android.support.multidex.MultiDexApplication">
    ...
</application>

*** 或者如果您有自己的应用程序类,那么必须扩展 MultiDexApplication 的 android:name=".yourAppllication"

欲了解更多信息 https://developer.android.com/tools/building/multidex.html

于 2015-08-03T06:18:57.843 回答
0

嗯......最后我想出了解决方案。

我无法详细解释,似乎在内部处理注释和 google-guice 依赖存在问题。

在我将版本移动到以下位置后,我的应用程序可以在整个 Android API 级别上完全运行:

compile 'com.google.inject:guice:4.0-beta5:no_aop'

它与 multidex 配置没有任何关系。

于 2015-02-10T21:00:02.420 回答
0

确保具有以下设置:

在 Android Studio 中使用资源设置 Multi Dex

更新

看起来真正的问题是 LoginForm 的初始化 java.lang.ExceptionInInitializerError引发了一个在第 22 行发生的 LoginForm 上的空指针MundoDescuentoApplication.java:22

拜托,你能发布这个课程的代码吗?

于 2015-02-09T21:24:15.000 回答