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


80

自从我更新到Android SDK Tools 25.1.6和Android Support Repository 32.0.0(今天上午)以来,出现以下错误,我没有更改代码中的任何内容,并且仍在我的同事计算机上正常工作(Android SDK Tools 25.1.1 + Android支持存储库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服务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 Cloud Messaging成为Firebase Cloud Messaging:firebase.google.com/docs/cloud-messaging不确定是否相关,仍在调查中。
索尼克

我觉得这不是构建工具问题。它与Google Play服务有关。我一直在使用9.0.0版,但仍然收到该错误以及抱怨我的签名无效的信息……
Arnold Balliu 2016年

您如何在手机上查看Google Play服务的版本?我看到Google Play音乐,游戏等,但没有Play服务。
bschandramohan '16

Answers:


37

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

只需运行gradle -q app:dependencies --configuration compile 并检查输出,如下所示:

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

正如Diego Giorgini所说,此版本过高(> = 24)。所以build.gradle像这样更新依赖

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

主要问题是一些使用+符号的模块导入支持库(例如您的示例)。因此gradle包含了最新版本,该版本无法容纳。谢谢!
Sonique

1
如果我们将所有内容都指定为24以下,我不明白Android如何将> = 24依赖项拖入我们的项目中。这似乎是一个新问题,现已使我的应用程序的调试版本变了砖,并引起了很多混乱-而使用相同代码的商店版本似乎还不错
Daniel Wilson

感谢stegranet的确认。我们只是发布了一个更新来解决此问题。请尝试版本9.0.1
Diego Giorgini,2016年


我在哪里运行以下代码?“ gradle -q app:dependencies --configuration compile”
Roee

35

5月27日更新:

我们刚刚发布了一个更新(version 9.0.1),以解决我在第一次编辑中提到的不兼容问题。
请更新您的依赖关系,并告诉我们是否仍然存在问题。

谢谢!


原答案5月20日:

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

您应该可以通过定位支持库的早期版本来修复它。喜欢:

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

2
谢谢,这是唯一可行的解​​决方案。如果您不介意我说的话,这样的错误可能会渗入生产版本,这有点令人恐惧!
丹尼尔·威尔逊,

我做到了,更新了:-编译了com.google.android.gms:play-services-gcm:9.0.2以及com.google.gms:google-services:3.0.0',但是它导致了multidex错误。任何的想法!!
罗希特(Rohit)2013年

'com.google.android.gms:播放服务-GCM:9.0.2'还是有这个问题
汤姆Bevelander

在项目构建中,将9.0.2用于我所有的“播放服务”模块和“ com.google.gms:google-services:3.0.0”。还使用了最近发布的24.0.0支持库。我能够消除将“ compile'c​​om.google.android.gms:play-services-gcm:9.0.2'”替换为“ compile'c​​om.google.firebase:firebase-messaging:9.0.2'”的错误
c0deblooded

尝试将版本更改为9.0.1时收到此错误>请通过更新google-services插件的版本来解决版本冲突(有关最新版本的信息,请访问bintray.com/android/android-tools/…)或将com.google.android.gms的版本更新为9.0.0。@迭戈
·

5

我的工作与以下人员:

应用程序级别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'
}

2
这对我有用...我将所有版本从24.2.1更改为23.4.0,getToken再次可用...这太糟糕了!现在,我不敢升级版本。
EZDsIt 2016年

5

我已经更新了Play服务依赖项 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-services的最新更新。

尽管它没有避免异常,但是并没有使应用程序崩溃。

更新资料

我可以通过从Beta频道更新Android Studio来避免崩溃。然后更新您的platform/build-tools内部SDK。

在此处输入图片说明


谢谢,我将google-services更新为3.0.0,但这无济于事:(
sonique

在我的情况下,我得到在logcat中的例外,但它不是崩溃了
雷阿兹穆尔希德

好的,谢谢您的反馈。您正在使用Android Build Tools 25.1.6吗?
索尼克

没错,它适用于播放服务9.0.0,但不适用于拆分服务:(
sonique

我做到了,更新了com.google.android.gms:play-services-gcm:9.0.2以及com.google.gms:google-services:3.0.0',但它导致multidex错误。任何的想法!!
罗希特(Rohit)

4

更新至最新的Google Play服务版本已为我解决了该问题。

在底部应用插件:“ 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


谢谢。我也确实更新9.0.0了,但仍然有问题。我目前正在使用splitd gms。: 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'
索尼克

我试图用编译play-services:9.0.0,但仍然是同样的问题。
Sonique

我正在使用“ com.google.android.gms:play-services-gcm:9.0.2”,但遇到了同样的问题
Tom Bevelander


1

通过包括所有播放服务的软件包

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。现在一切似乎运转良好。


听起来我们必须执行FCM
索尼克

我做到了,我仍然遇到相同的错误。我完全删除了GCM,并根据以下内容将其替换为FCM:developers.google.com/cloud-messaging/android / ...支持库出了点问题,而不是GCM或FCM包
Stilianos Tzouvaras

1

我遇到了同样的问题,从Android支持存储库32.0.0还原到Android支持存储库31.0.0解决了该问题。


3
您如何还原android支持存储库?
Pratama Nur Wijaya

2
好吧,我发现的唯一方法是复制旧存储库而不是新存储库。该存储库通常位于“ SDK管理器”所指向的Android文件夹下(如果您使用的是Mac,则可能是〜/ Library / Android / sdk / extras路径)。在extras文件夹中,将“ android”和“ google”文件夹替换为旧文件夹。
BorisK '16

我在以下位置找到了该存储库:dl-ssl.google.com/android/repository/…,然后将其解压缩到../sdk/extras/android并删除现有的m2reposity似乎可以正常工作。
Tom Redman

1

对于GCM 2016的Android推送通知:

1)在Android SDK-> SDK Tools中检查Google Play服务

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

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

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

3)您必须创建3个类(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中复制令牌并粘贴到此站点上, 添加您的项目编号,令牌和消息。对我来说很好


@Skygirl大家好,我正在关注您的示例,AndroidManifest中是否有特殊要求?您能否添加部分代码?谢谢
ziniestro '16

0

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

我已经在他们的github上发布了有关它的信息,并将直接与他们联系...

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


0

我有同样的问题。我将SDK工具更新为25.1.7 rc1,然后问题消失了。



0

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

我在指定的位置添加了这些行。

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

编译'com.google.firebase:firebase-auth:9.2.0'

应用插件:“ com.google.gms.google-services”

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

但是,当我检查时logcat,它首先显示"Firebase API initialization failure",然后显示“ FirebaseApp初始化成功”。

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

这个?com.google.firebase.FirebaseApp.zza上java.lang.reflect.Method.invoke(Method.java:515)上java.lang.reflect.Method.invokeNative(本机方法)的java.lang.reflect.InvocationTargetException(未知来源)com.google.firebase.FirebaseApp.initializeApp(未知来源)com.google.firebase.FirebaseApp。


好。谢谢。我认为最好分享我如何解决我的问题。(只是我不确定我是否能完全解决它。我可以在更新Android Studio版本后使用com.google.firebase:firebase-auth:9.2.0创建用户,但在logcat中仍然存在Firebase API初始化失败。所以我很纳闷)下一次我将使用“问问题按钮”。
Jayground '16

0

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

改变类路径

com.android.tools.build:gradle:1.5.0

classpath 'com.android.tools.build:gradle:2.0.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。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.