【问题标题】:ClassCastException while executing my app with minifyEnabled true使用 minifyEnabled true 执行我的应用程序时出现 ClassCastException
【发布时间】:2020-05-07 19:44:15
【问题描述】:

我有一个 Android 系统应用,它在清单中有一个自定义的 BroadCastReceiver(这将在 Android M 设备中运行): 我的清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:sharedUserId="android.uid.system"
    package="mypackagename">

   ....

    <!-- custom permissions -->
    <uses-permission android:name="mypackagename.ASK_DISPLAY_INFO"
        android:protectionLevel="signatureOrSystem"/>

    <permission android:name="mypackagename.ASK_DISPLAY_INFO" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
         
        ....

        <!-- custom receiver -->
        <receiver android:name=".CustomReceiver"
            android:permission="mypackagename.ASK_DISPLAY_INFO">
            <intent-filter>
                <action android:name="GET_HDMI_SUPPORTED_MODES"/>
                <action android:name="CHANGE_HDMI_RESOLUTION"/>
            </intent-filter>
        </receiver>



    </application>

</manifest>

我已经在 gradle Proguard 中启用了混淆:

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

我有另一个向该应用发送广播的测试应用。问题是,使用 mignifyEnabled false 有效,但使用 mignifyEnabled true 在接收到广播意图时会给出错误:

java.lang.RuntimeException:无法实例化接收器 mypackagename.CustomReceiver:java.lang.ClassCastException:mypackagename.CustomReceiver 无法转换为 android.content.BroadcastReceiver

将以下规则添加到 proguard-rules.pro:

-keep class android.content.BroadcastReceiver { *; }

当接收到意图时抛出错误:

java.lang.AbstractMethodError:抽象方法“void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)”

这是我的广播接收器定义:


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;


public class CustomReceiver extends BroadcastReceiver {
    ...

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null) {
            Log.i(TAG, "CustomReceiver received action: "+intent.getAction());

            if (intent.getAction().equals(GET_HDMI_SUPPORTED_MODES)) {
                new GetHDMIModesTask(context).execute();
            }  else if (intent.getAction().equals(CHANGE_HDMI_RESOLUTION) && intent.getExtras() != null && intent.hasExtra(EXTRA_HDMI_MODE) ) {
                new ChangeHDMIModeTask(context, intent.getStringExtra(EXTRA_HDMI_MODE)).execute();
            }
        }

    }

}

由于我对 Proguard 规则非常陌生,我需要对此进行混淆处理,如果有人能告诉我可以指定哪些规则来解决此问题,我将不胜感激

【问题讨论】:

  • 似乎问题出在CustomReceiver 所以发布确保它扩展BroadcastReceiver 并且导入是适当的
  • 您好,谢谢您的回答,我已将广播接收器添加到帖子中。
  • 如果您在单独的应用程序中使用广播,请添加android:exported="true" 虽然对于专业人士来说,Nikhil 的回答应该可以解决问题,清理并生成新的 apk 并重试

标签: android gradle broadcastreceiver proguard classcastexception


【解决方案1】:

-keep public class * extends android.content.BroadcastReceiver 添加到您的proguard 规则中,而不是-keep class android.content.BroadcastReceiver { *; }。这将防止您的自定义广播接收器被混淆。

【讨论】:

  • 您好,感谢您的建议,我已添加到 proguard 规则:-keep public class * extends android.content.BroadcastReceiver 但仍然返回第一个错误:java.lang.RuntimeException: Unable to instantiate receiver mypackagename .CustomReceiver: java.lang.ClassCastException: mypackagename.CustomReceiver 无法转换为 android.content.BroadcastReceiver
  • 尝试保留这两行 - -keep public class * extends android.content.BroadcastReceiver-keep class android.content.BroadcastReceiver { *; }
  • 添加两个规则会引发第二个错误:java.lang.AbstractMethodError: abstract method "void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.意图)
  • 尝试添加-keepnames class your.package.name.ClassName { },明确告诉proguard不要混淆类。
  • 它没有构建:AGPBI: {"kind":"error","text":"Expected [!]interface|@interface|class|enum","sources":[{ "file":"C:\\...\proguard-rules.pro","position":{"startLine":34,"startColumn":11,"startOffset":1295}}],"tool": “R8”} FAILURE:构建失败,出现异常。
【解决方案2】:

我已经解决了这个问题,从清单中删除了 CustomerReceiver,添加了一个自定义应用程序类并在其中定义了 BroadcastReceiver。添加了proguard规则:

 -keep class android.app.Application {
        public <fields>;
        private <fields>;
       public <methods>;
    }

    -keep public class * extends android.app.Application

问题解决了

【讨论】:

    猜你喜欢
    • 2017-05-31
    • 2021-10-20
    • 2017-07-25
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多