更新到 Android Build Tools 25.1.6 GCM / FCM 后出现 IncompatibleClassChangeError

IncompatibleClassChangeError after updating to Android Build Tools 25.1.6 GCM / FCM

自从我更新到 Android SDK Tools 25.1.6 和 Android Support Repository 32.0.0(今天早上),我收到以下错误,我没有更改我的代码中的任何内容它仍在我同事的计算机上运行(Android SDK Tools 25.1.1 + Android Support Repository 30.0.0)。

java.lang.IncompatibleClassChangeError: The method 
     'java.io.File android.support.v4.content.ContextCompat.getNoBackupFilesDir(android.content.Context)' 
     was expected to be of type virtual but instead was found to be of type direct 
     (declaration of 'java.lang.reflect.ArtMethod' appears in /system/framework/core-libart.jar)

     at com.google.android.gms.iid.zzd.zzeb(Unknown Source)
     at com.google.android.gms.iid.zzd.<init>(Unknown Source)
     at com.google.android.gms.iid.zzd.<init>(Unknown Source)
     at com.google.android.gms.iid.InstanceID.zza(Unknown Source)
     at com.google.android.gms.iid.InstanceID.getInstance(Unknown Source)
     at com.xxxxxxx.utils.RegistrationIntentService.onHandleIntent(RegistrationIntentService.java:55)
     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:145)
     at android.os.HandlerThread.run(HandlerThread.java:61)

这是一段崩溃的代码:

InstanceID instanceID = InstanceID.getInstance(this); // <-- crash here
String instanceIDToken = instanceID.getToken(getString(R.string.google_app_id),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

这是我尝试从 Google Cloud Messaging 获取令牌的时候。

我正在 Gradle 中导入 GCM 并使用拆分播放服务:

 compile 'com.google.android.gms:play-services-analytics:9.0.0' 
 compile 'com.google.android.gms:play-services-maps:9.0.0'
 compile 'com.google.android.gms:play-services-location:9.0.0' 
 compile 'com.google.android.gms:play-services-gcm:9.0.0' 
 compile 'com.google.android.gms:play-services-base:9.0.0'

编辑 禁用 GCM 解决了这个问题,所以我猜我应该迁移到 Firebase Cloud Message

EDIT2 我的设备收到 Google Play Services 9.0(昨天是 8.4.x)。现在它不再崩溃了,但是抱怨模块描述符

 Failed to load module descriptor class: Didn't find class "com.google.android.gms.dynamite.descriptors.com.google.firebase.auth.ModuleDescriptor"
 Firebase API initialization failure.

有没有人有类似的错误,如何解决?

固定 特别感谢@stegranet。 ./gradlew -q app:dependencies --configuration compile 帮助您识别哪些依赖项包含 SDK 24.x

主要问题是一些库使用 + 符号而不是版本导入最新的支持库。这导致了问题,包括最新的可用版本。

所以避免 + 登录依赖项 ;)

更新到最新的 google 播放服务版本为我解决了这个问题。

应用插件:'com.google.gms.google-services' 在底部 ...

dependencies {
    compile 'com.google.android.gms:play-services:9.0.0'
}

https://developers.google.com/android/guides/setup#add_google_play_services_to_your_project

我已经在 build.gradle

中更新了播放服务依赖项
dependencies {
    compile 'com.google.android.gms:play-services:9.0.0'
}

要通过更新 google-services 插件的版本来解决版本冲突 - 我必须更新项目根文件夹下 build.gradle 中的 google-services

dependencies {
    classpath 'com.google.gms:google-services:3.0.0'
}

您可以获得google服务的最新更新here

虽然它没有避免异常,但它不再让我这边的应用程序崩溃。

更新

我可以通过从 Beta 频道更新 Android 工作室来避免崩溃。然后在 SDK 中更新您的 platform/build-tools

通过包含所有播放服务的包

dependencies {
  compile 'com.google.android.gms:play-services:9.0.0'
}

您抑制了错误,但最终结果是 GCM 令牌检索不起作用,我们也无法获得 GCM 的实例。所以这不是我书中的解决方案。如果有人知道这是怎么回事,请赐教。

编辑:

我用 firebase 替换了 GCM,将 android studio 从 2.1 更新到 2.2 以修复 firebase 分析的即时 运行 问题,将构建工具更新为 24-rc4,将平台工具更新为 24-rc3 ,并将我的支持库版本保持为 23.4.0。现在似乎一切正常。

我的工作是通过以下方式进行的:

应用级别gradle

dependencies {
 compile 'com.android.support:appcompat-v7:23.4.0'
 compile 'com.android.support:design:23.4.0'
 compile 'com.google.android.gms:play-services:9.0.0'
}

根级别gradle

dependencies {
    classpath 'com.google.gms:google-services:3.0.0'
}

5 月 27 日更新:

我们刚刚发布了一个更新 (version 9.0.1) 来修复我在第一次编辑中提到的不兼容问题。
请更新您的依赖项,如果这仍然是一个问题,请告诉我们。

谢谢!


5月20日原回答:

您遇到的问题是由于
之间的不兼容造成的 play-services / firebase sdk v9.0.0com.android.support:appcompat-v7 >= 24
(与android-N sdk一起发布的版本)

您应该能够通过针对早期版本的支持库来修复它。喜欢:

compile 'com.android.support:appcompat-v7:23.4.0'

我使用 gradle 依赖树为我解决了这个错误。

刚刚运行gradle -q app:dependencies --configuration compile 并检查这样的条目的输出:

+--- com.mcxiaoke.viewpagerindicator:library:2.4.1
|    \--- com.android.support:support-v4:+ -> 24.0.0-beta1 (*)

正如所说,这个版本太高了(>=24)。 所以更新 build.gradle 中的依赖项,例如

compile('com.mcxiaoke.viewpagerindicator:library:2.4.1') {
    exclude module: 'support-v4';
}
compile 'com.android.support:support-v4:23.4.0'

经过一整天的思考,我可以 100% 确认 Optimizely 库也在某种程度上发生冲突并导致此错误。具体来说,我正在通过 Fabric 使用 Optimizely。以这种方式使用 Optimizely 时不可能让 Firebase 初始化(也许在所有方面?)。

我已经在他们的 github 上发帖了,我会直接联系他们...

https://github.com/optimizely/Optimizely-Android-SDK/issues/11

我遇到了同样的问题。 我更新了SDK工具到25.1.7 rc1,然后问题就没有了。

我遇到了同样的问题,从 Android Support Repository 32.0.0 恢复到 Android Support Repository 31.0.0 解决了这个问题。

将 SDK 工具更新到 25.1.7 并修复了这个问题。

嗯,我只是使用 Android 的初学者。 我想按照 Firebase 网站中提供的说明在 Firebase 中测试创建用户。

我在指定的地方添加了这些行。

classpath 'com.google.gms:google-services:3.0.0'

compile 'com.google.firebase:firebase-auth:9.2.0'

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

但是createUserWithEmailAndPassword方法一直显示创建用户失败。这就是为什么我访问这个问题来找出我的问题。我阅读了所有内容并采纳了每条建议。但 IT 一直显示失败。但是当我升级Android Studio from 2.1.1 to 2.1.2时,我可以成功创建用户。

但是我查看logcat的时候,先显示"Firebase API initialization failure",然后显示"FirebaseApp initialization successful"。

07-09 18:53:37.012 13352-13352/jayground.firebasetest A/FirebaseApp: Firebase API initialization failure. How can I solve

this? java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.google.firebase.FirebaseApp.zza(Unknown Source) at com.google.firebase.FirebaseApp.initializeApp(Unknown Source) at com.google.firebase.FirebaseApp.initializeApp(Unknown Source) at com.google.firebase.FirebaseApp.zzeh(Unknown Source) at com.google.firebase.provider.FirebaseInitProvider.onCreate(Unknown Source) at android.content.ContentProvider.attachInfo(ContentProvider.java:1591) at android.content.ContentProvider.attachInfo(ContentProvider.java:1562) at com.google.firebase.provider.FirebaseInitProvider.attachInfo(Unknown Source) at android.app.ActivityThread.installProvider(ActivityThread.java:5118) at android.app.ActivityThread.installContentProviders(ActivityThread.java:4713) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4596) at android.app.ActivityThread.access00(ActivityThread.java:169) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1340) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5487) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NoSuchMethodError: com.google.android.gms.common.internal.zzaa.zzz at com.google.android.gms.measurement.internal.zzx.zzbd(Unknown Source) at com.google.android.gms.measurement.AppMeasurement.getInstance(Unknown Source) at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.google.firebase.FirebaseApp.zza(Unknown Source)  at com.google.firebase.FirebaseApp.initializeApp(Unknown Source)  at com.google.firebase.FirebaseApp.initializeApp(Unknown Source)  at com.google.firebase.FirebaseApp.zzeh(Unknown Source)  at com.google.firebase.provider.FirebaseInitProvider.onCreate(Unknown Source)  at android.content.ContentProvider.attachInfo(ContentProvider.java:1591)  at android.content.ContentProvider.attachInfo(ContentProvider.java:1562)  at com.google.firebase.provider.FirebaseInitProvider.attachInfo(Unknown Source)  at android.app.ActivityThread.installProvider(ActivityThread.java:5118)  at android.app.ActivityThread.installContentProviders(ActivityThread.java:4713)  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4596)  at android.app.ActivityThread.access00(ActivityThread.java:169)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1340)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:146)  at android.app.ActivityThread.main(ActivityThread.java:5487)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)  at dalvik.system.NativeStart.main(Native Method)  07-09 18:53:37.022 13352-13352/jayground.firebasetest I/FirebaseInitProvider: FirebaseApp initialization successful

对于 Android 使用 GCM 2016 的推送通知:

1) 在Android SDK-> SDK Tools 检查Google Play services

2) 在 gradle 中仅添加一行依赖项:

compile 'com.google.android.gms:play-services-gcm:9.4.0'

(没有特定的 class 路径,对我有用)

3) 你必须创建 3 class (GCMPushReceiverService, GCMRegistrationIntentService, GCMTokenRefreshListenerService)

4.1) GCMTokenRefreshListenerService 代码:

package com.myapp.android;

/**
 * Created by skygirl on 02/08/2016.
 */
import android.content.Intent;
import com.google.android.gms.iid.InstanceIDListenerService;

public class GCMTokenRefreshListenerService extends InstanceIDListenerService {

    //If the token is changed registering the device again
    @Override
    public void onTokenRefresh() {
        Intent intent = new Intent(this, GCMRegistrationIntentService.class);
        startService(intent);
    }
}

4.2) GCMRegistrationIntentService 代码(用您的项目编号更改 authorizedEntity):

package com.myapp.android;

/**
 * Created by Skygirl on 02/08/2016.
 */
import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;

public class GCMRegistrationIntentService extends IntentService {
    //Constants for success and errors
    public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
    public static final String REGISTRATION_ERROR = "RegistrationError";

    //Class constructor
    public GCMRegistrationIntentService() {
        super("");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        //Registering gcm to the device
        registerGCM();
    }

    private void registerGCM() {
        //Registration complete intent initially null
        Intent registrationComplete = null;

        //Register token is also null
        //we will get the token on successfull registration
        String token = null;
        try {
            //Creating an instanceid
            InstanceID instanceID = InstanceID.getInstance(this);
            String authorizedEntity = "XXXXXXXXXX"; //  your project number

            //Getting the token from the instance id
            token = instanceID.getToken(authorizedEntity, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

            //Displaying the token in the log so that we can copy it to send push notification
            //You can also extend the app by storing the token in to your server
            Log.w("GCMRegIntentService", "token:" + token);

            //on registration complete creating intent with success
            registrationComplete = new Intent(REGISTRATION_SUCCESS);

            //Putting the token to the intent
            registrationComplete.putExtra("token", token);
        } catch (Exception e) {
            //If any error occurred
            Log.w("GCMRegIntentService", "Registration error");
            registrationComplete = new Intent(REGISTRATION_ERROR);
        }

        //Sending the broadcast that registration is completed
        LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
    }
}

4.3) GCMPushReceiverService 代码:

package com.myapp.android;

/**
 * Created by Skygirl on 02/08/2016.
 */
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;

import com.google.android.gms.gcm.GcmListenerService;

//Class is extending GcmListenerService
public class GCMPushReceiverService extends GcmListenerService {

    //This method will be called on every new message received
    @Override
    public void onMessageReceived(String from, Bundle data) {
        //Getting the message from the bundle
        String message = data.getString("message");
        //Displaying a notiffication with the message
        sendNotification(message);
    }

    //This method is generating a notification and displaying the notification
    private void sendNotification(String message) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        int requestCode = 0;
        PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
        NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.your_logo)
                .setContentTitle("Your Amazing Title")
                .setContentText(message)
                .setPriority(Notification.PRIORITY_MAX)
                .setContentIntent(pendingIntent);
        noBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));

        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
    }
}

5) 不要忘记更改包名称

6) 在您的 mainActivity 中粘贴此代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Setup view
        setContentView(R.layout.main);
    mRegistrationBroadcastReceiver = new BroadcastReceiver() {

        //When the broadcast received
        //We are sending the broadcast from GCMRegistrationIntentService

        public void onReceive(Context context, Intent intent) {
            //If the broadcast has received with success
            //that means device is registered successfully
            if(intent.getAction().equals(GCMRegistrationIntentService.REGISTRATION_SUCCESS)){
                //Getting the registration token from the intent
                String token = intent.getStringExtra("token");
                //Displaying the token as toast
                Toast.makeText(getApplicationContext(), "Registration token:" + token, Toast.LENGTH_LONG).show();

                //if the intent is not with success then displaying error messages
            } else if(intent.getAction().equals(GCMRegistrationIntentService.REGISTRATION_ERROR)){
                Toast.makeText(getApplicationContext(), "GCM registration error!", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getApplicationContext(), "Error occurred", Toast.LENGTH_LONG).show();
            }
        }
    };

    //Checking play service is available or not
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

    //if play service is not available
    if(ConnectionResult.SUCCESS != resultCode) {
        //If play service is supported but not installed
        if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            //Displaying message that play service is not installed
            Toast.makeText(getApplicationContext(), "Google Play Service is not install/enabled in this device!", Toast.LENGTH_LONG).show();
            GooglePlayServicesUtil.showErrorNotification(resultCode, getApplicationContext());

            //If play service is not supported
            //Displaying an error message
        } else {
            Toast.makeText(getApplicationContext(), "This device does not support for Google Play Service!", Toast.LENGTH_LONG).show();
        }

        //If play service is available
    } else {
        //Starting intent to register device
        Intent itent = new Intent(this, GCMRegistrationIntentService.class);
        startService(itent);
    }
}

//Unregistering receiver on activity paused
@Override
public void onPause() {
    super.onPause();
    Log.w("MainActivity", "onPause");
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
}



    @Override
    public void onResume() {
 super.onResume();
        Log.w("MainActivity", "onResume");
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(GCMRegistrationIntentService.REGISTRATION_SUCCESS));
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(GCMRegistrationIntentService.REGISTRATION_ERROR));
    }

7) 在您的 AndroidManifest.xml 中添加以下行:

<uses-permission android:name="android.permission.INTERNET" />

8) 在您的控制台中 logcat 复制您的令牌并粘贴到此 site 添加您的项目编号、您的令牌和一条消息。这对我来说很好:)

我遇到了这个问题,我将我的应用 gradle 版本从 1.5.0 更改为 2.0.0。

改变 类路径

com.android.tools.build:gradle:1.5.0

classpath 'com.android.tools.build:gradle:2.0.0

解决方案 1:

dependencies {
 compile `com.android.support:appcompat-v7:23.4.0`
 compile `com.android.support:support-v4:23.4.0`
 compile `com.android.support:design:23.4.0`
 compile `com.google.android.gms:play-services:9.0.0`
}

解决方案 2:检测文件夹不兼容。idie/libraries/ .有时你声明 play-services-ads:8.4.0 与 play-services-gcm:9.0.0 同时 .您必须覆盖 build.grade 个您检测到的不兼容库

发生在我​​身上是因为 facebook 更新了它的 sdk 我有

compile 'com.facebook.android:facebook-android-sdk:4.+'

将其替换为

compile 'com.facebook.android:facebook-android-sdk:4.15.0'

解决了我的问题。

参考:https://developers.facebook.com/docs/android/change-log-4.x

我们在带有消息的发布版本中遇到了类似的问题

“该方法 (com.xx.classname.method) 应为虚拟类型,但被发现为静态类型(伴随对象的声明出现在 submodule.apk 中)

问题已通过为 okhttp3 添加 proguard 规则得到解决