获取java.lang.NoClassDefFoundError:com.google.firebase.FirebaseOptions即使启用了Multidex也是如此

时间:2016-10-04 12:03:25

标签: android google-maps firebase

我有一个使用Firebase和Google Maps的Android应用程序。我在JellyBean上的真实设备上启动了应用程序。我启用了multidex并尝试了很多其他解决方案,但我仍然无法解决错误。

这是我的代码。 gradle文件:

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "24.0.3"

defaultConfig {
    applicationId "com.codehacker.pocketambulance"
    minSdkVersion 16
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
    generatedDensities = []
    multiDexEnabled true
}

dexOptions {
    javaMaxHeapSize "4g"
}

aaptOptions {
    additionalParameters "--no-version-vectors"
}

buildTypes 
{
   release 
   {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
   }
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.firebaseui:firebase-ui:0.4.4'
compile 'com.google.android.gms:play-services:9.6.1'
compile 'com.android.support:multidex:1.0.1'
}

apply plugin: 'com.google.gms.google-services'

我还在我的主要activity.java中使用了Multidex.install(this);

 package com.codehacker.pocketambulance;

 import android.content.Intent;
 import android.os.Bundle;
 import android.support.multidex.MultiDex;
 import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
 import android.widget.Toast;

 import com.firebase.ui.auth.AuthUI;
 import com.google.firebase.auth.FirebaseAuth;

 public class MainActivity extends AppCompatActivity{
 private static final int RC_SIGN_IN=0;
 private FirebaseAuth auth;
 ConnectionDetector cd;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MultiDex.install(this);
     setContentView(R.layout.activity_main);

    cd=new ConnectionDetector(this);
    if(cd.isConnected())
    {
        auth= FirebaseAuth.getInstance();
        if(auth.getCurrentUser()!=null)
        {
            //user already signed in
            Log.d("AUTH",auth.getCurrentUser().getEmail());
            Toast.makeText(MainActivity.this,"User Already logged in",Toast.LENGTH_LONG).show();
        }
        else
        {
            startActivityForResult(AuthUI.getInstance()
                    .createSignInIntentBuilder()
                    .setProviders(AuthUI.GOOGLE_PROVIDER,
                            AuthUI.EMAIL_PROVIDER,
                            AuthUI.FACEBOOK_PROVIDER).build(),RC_SIGN_IN);
        }

    }
    else
    {
        Toast.makeText(MainActivity.this,"Not Connected to internet",Toast.LENGTH_LONG).show();
        Log.d("AUTH","No internet connection");
    }

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode==RC_SIGN_IN)
    {
        if(resultCode==RESULT_OK)
        {
            //user logged in
            Log.d("AUTH",auth.getCurrentUser().getEmail());
            Toast.makeText(MainActivity.this,"User logged in successfully",Toast.LENGTH_LONG).show();
        }
        else
        {
            //User not authenticated
            Log.d("AUTH","NOT AUTHENTICATED");
        }
    }
}
}

我也尝试过use-permission这里是我的清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codehacker.pocketambulance">

<permission
    android:name="com.codehacker.pocketambulance.permission.MAPS_RECEIVE"
    android:protectionLevel="signature" />


<uses-permission android:name="com.codehacker.pocketambulance.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.support.multidex.MultiDexApplication"/>

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <!--
         The API key for Google Maps-based APIs is defined as a string resource.
         (See the file "res/values/google_maps_api.xml").
         Note that the API key is linked to the encryption key used to sign the APK.
         You need a different API key for each encryption key, including the release key that is used to
         sign the APK for publishing.
         You can define the keys for the debug and release targets in src/debug/ and src/release/. 
    -->
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps" />
</application>

堆栈跟踪:

    FATAL EXCEPTION: main                    java.lang.NoClassDefFoundError: com.google.firebase.FirebaseOptions
                                                   at com.google.firebase.FirebaseApp.initializeApp(Unknown Source)
                                                   at com.google.firebase.provider.FirebaseInitProvider.onCreate(Unknown Source)
                                                   at android.content.ContentProvider.attachInfo(ContentProvider.java:1214)
                                                   at android.content.ContentProvider.attachInfo(ContentProvider.java:1189)
                                                   at com.google.firebase.provider.FirebaseInitProvider.attachInfo(Unknown Source)
                                                   at android.app.ActivityThread.installProvider(ActivityThread.java:4912)
                                                   at android.app.ActivityThread.installContentProviders(ActivityThread.java:4518)
                                                   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4458)
                                                   at android.app.ActivityThread.access$1300(ActivityThread.java:144)
                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1319)
                                                   at android.os.Handler.dispatchMessage(Handler.java:99)
                                                   at android.os.Looper.loop(Looper.java:137)
                                                   at android.app.ActivityThread.main(ActivityThread.java:5136)
                                                   at java.lang.reflect.Method.invokeNative(Native Method)
                                                   at java.lang.reflect.Method.invoke(Method.java:525)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                   at dalvik.system.NativeStart.main(Native Method)

2 个答案:

答案 0 :(得分:0)

您正在使用

compile 'com.firebaseui:firebase-ui:0.4.4'
compile 'com.google.android.gms:play-services:9.6.1'

如果您的ui版本为0.4.4,则播放服务版本应为9.4.0

检查here以查找相应的播放和ui服务版本

答案 1 :(得分:0)

Firebase初始化发生在创建ContentProvider之前在应用初始化序列的早期创建的MainActivity中。您无法在Multidex.install()中致电MainActivity - 为时已晚。初始化Multidex的最简单方法是在清单中将MultiDexApplication指定为Application类。这在instructions for configuring Multidex中有描述,需要在清单中添加一行:

android:name="android.support.multidex.MultiDexApplication"

此外,在构建中包含整个Play服务库并不是一个好习惯:

compile 'com.google.android.gms:play-services:9.6.1'

这会添加每个 Play服务和Firebase API,这会增加构建时间,使您的APK更大,并且可能是您需要Multidex的原因。最好只包含实际需要的API库。完整的API列表在{em>选择性地将API编译为可执行文件的部分中为provided here