flutter 运行直接报错 D8: java.lang.IllegalArgumentException

博客记录了Gradle构建时出现的错误,包括java.lang.IllegalArgumentException和java.lang.StackOverflowError,构建失败并给出了相关提示。同时提供了解决办法,即在build.gradle中开启multiDexEnabled true。

D8: java.lang.IllegalArgumentException

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ‘:app:mergeDexDebug’.

A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
java.lang.StackOverflowError (no error message)

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 10s
Exception: Gradle task assembleDebug failed with exit code 1

在build.gradle中开启:
defaultConfig {
multiDexEnabled true
}

E/JavaBinder(13627): *** Uncaught remote exception! (Exceptions are not yet supported across processes.) E/JavaBinder(13627): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long E/JavaBinder(13627): at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:310) E/JavaBinder(13627): at com.tencent.tpns.baseapi.base.SettingsContentProvider.query(ProGuard:187) E/JavaBinder(13627): at android.content.ContentProvider.query(ContentProvider.java:1058) E/JavaBinder(13627): at android.content.ContentProvider.query(ContentProvider.java:1150) E/JavaBinder(13627): at android.content.ContentProvider$Transport.query(ContentProvider.java:242) E/JavaBinder(13627): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:102) E/JavaBinder(13627): at android.os.Binder.execTransact(Binder.java:731) E/JavaBinder(13627): *** Uncaught remote exception! (Exceptions are not yet supported across processes.) E/JavaBinder(13627): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long E/JavaBinder(13627): at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:310) E/JavaBinder(13627): at com.tencent.tpns.baseapi.base.SettingsContentProvider.query(ProGuard:187) E/JavaBinder(13627): at android.content.ContentProvider.query(ContentProvider.java:1058) E/JavaBinder(13627): at android.content.ContentProvider.query(ContentProvider.java:1150) E/JavaBinder(13627): at android.content.ContentProvider$Transport.query(ContentProvider.java:242) E/JavaBinder(13627): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:102) E/JavaBinder(13627): at android.os.Binder.execTransact(Binder.java:731) E/JavaBinder(13627): *** Uncaught remote exception! (Exceptions are not yet supported across processes.) E/JavaBinder(13627): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long E/JavaBinder(13627): at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:310) E/JavaBinder(13627): at com.tencent.tpns.baseapi.base.SettingsContentProvider.query(ProGuard:187) E/JavaBinder(13627): at android.content.ContentProvider.query(ContentProvider.java:1058) E/JavaBinder(13627): at android.content.ContentProvider.query(ContentProvider.java:1150) E/JavaBinder(13627): at android.content.ContentProvider$Transport.query(ContentProvider.java:242) E/JavaBinder(13627): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:102) E/JavaBinder(13627): at android.os.Binder.execTransact(Binder.java:731) flutter 项目运行成功,控制台输出以下信息是什么意思
08-14
<think>我们正在处理一个Flutter项目运行时的JavaBinder异常,具体是ClassCastException,涉及Integer到Long的转换错误。这个错误发生在Android平台上,因为Flutter应用在Android上运行时使用的是Java/Kotlin代码。错误信息表明在通过Binder进行跨进程通信(IPC)时,尝试将一个Integer类型的对象转换为Long类型,导致类型不匹配。 ### 错误原因分析 1. **Binder机制**:在Android中,Binder用于跨进程通信。当进行IPC调用时,数据需要被序列化并通过Binder传递。在传递过程中,如果发送方和接收方对同一数据的类型解释不一致(例如,一方使用Integer而另一方使用Long),就会抛出`ClassCastException`。 2. **类型不匹配**:具体错误是`java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long`。这意味着某个地方期望得到一个`Long`对象,但实际传递的是一个`Integer`对象。 3. **可能的原因**: - **方法签名不匹配**:在AIDL接口定义中,某个方法参数或返回值声明为`long`(或`Long`),但实际实现或调用时传递了`int`(或`Integer`)。 - **Bundle传递错误**:在使用`Bundle`传递数据时,键值对中的值类型在读取时与存入时不一致。例如,用`putInt`存入,但用`getLong`读取。 - **Parcelable对象序列化问题**:自定义的`Parcelable`对象在`writeToParcel`和`createFromParcel`方法中读写顺序或类型不一致。 ### 排查步骤 1. **检查AIDL文件**:如果项目中使用AIDL定义了跨进程接口,检查接口方法中参数和返回值的数据类型。确保调用方和被调用方使用相同的基本类型(如用`long`而不是`int`)。 2. **检查Bundle的使用**:查找代码中使用`Bundle`的地方,特别是使用`getLong`和`getInt`的地方,确认对应的键值是否确实存储了相应类型。例如: ```java bundle.putInt("key", 123); // 错误,如果后面用getLong取就会出问题 bundle.getLong("key"); // 会抛出ClassCastException ``` 3. **检查Parcelable实现**:如果自定义了`Parcelable`类,确保在`writeToParcel`和`createFromParcel`中读写顺序和类型严格一致。例如: ```java @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(someValue); // 写入long } public static final Creator<MyParcelable> CREATOR = new Creator<MyParcelable>() { @Override public MyParcelable createFromParcel(Parcel in) { // 读取顺序必须与写入一致 long value = in.readLong(); // 如果写入的是int,这里读long就会出错 return new MyParcelable(value); } }; ``` 4. **检查第三方库或Flutter插件**:如果使用了Flutter插件,可能是插件中的原生代码存在类型不匹配。检查插件代码中涉及Binder通信或Bundle传递的部分。 5. **查看完整堆栈跟踪**:控制台输出的异常堆栈通常会指出错误发生的具体位置。根据堆栈信息定位到代码行,分析该行代码的类型转换。 ### 解决方案 一旦定位到问题,可以采取以下措施: - **修改类型声明**:将AIDL接口中的参数类型从`int`改为`long`,或者反之(确保两端一致)。 - **修正Bundle操作**:统一使用同一种类型,或者使用`get`方法获取值后再进行类型转换(注意避免直接强制转换)。 - **修正Parcelable读写**:确保读写顺序和类型一致。 - **更新或修复插件**:如果是第三方插件的问题,考虑升级插件版本或提交issue给插件作者。 ### 示例:修正Bundle操作 假设在某个Activity中: ```java // 错误示例 Bundle bundle = new Bundle(); bundle.putInt("user_id", 12345); // 存入int long userId = bundle.getLong("user_id"); // 尝试取出long -> 抛出异常 ``` 修正为: ```java // 正确做法1:存入long bundle.putLong("user_id", 12345L); long userId = bundle.getLong("user_id"); // 正确做法2:如果必须用int,则取出时用int,然后转为long int intValue = bundle.getInt("user_id"); long userId = (long) intValue; ``` ### 总结 该错误通常是由于跨进程通信中类型不一致导致的。通过仔细检查涉及Binder通信的代码(如AIDL接口、Bundle、Parcelable等),确保类型匹配,即可解决此问题。 §§相关问题§§ 1. 如何查看Flutter运行时的完整原生堆栈信息? 2. Flutter与原生平台通信时还有哪些常见错误? 3. 如何调试Flutter插件的原生代码?</think>### Flutter控制台JavaBinder异常分析 您在Flutter项目中遇到的`ClassCastException: Integer cannot be cast to Long`错误是Android平台上常见的类型转换异常,主要发生在Java/Kotlin原生代码层。以下是详细分析: #### 错误原因 1. **跨进程通信类型不匹配**: - Binder是Android的IPC(跨进程通信)机制 - 当通过`Intent`或`Bundle`传递数据时,发送方使用`putInt()`存储Integer,接收方却用`getLong()`读取 - 示例代码: ```java // 发送方 intent.putExtra("key", 123); // Integer // 接收方错误 long value = intent.getLongExtra("key", 0L); // 尝试转为Long ``` 2. **Flutter插件兼容性问题**: - 第三方插件未正确处理数据类型 - 插件与Android SDK版本不兼容(常见于targetSdkVersion≥24时强化的类型检查) 3. **Parcelable序列化错误**: - 自定义Parcelable对象在`writeToParcel()`和`createFromParcel()`中类型不一致 #### 解决方案 1. **检查数据传递代码**: ```java // 正确做法:类型匹配 int intValue = bundle.getInt("key"); long longValue = bundle.getLong("key"); // 确保存储时是Long ``` 2. **更新Flutter环境**: ```bash flutter upgrade # 升级Flutter SDK flutter pub outdated # 检查插件更新 ``` 3. **调试插件**: - 在`android/app/src/main/java`中搜索`getInt`/`getLong` - 使用Android Studio调试原生代码(在`run`配置中勾选"Enable Android debugging") 4. **强制类型转换保护**: ```java Object value = bundle.get("key"); if (value instanceof Integer) { long safeValue = ((Integer) value).longValue(); } ``` #### 典型错误日志分析 ```log E/JavaBinder: *** Uncaught remote exception! java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long at android.os.BaseBundle.getLong(BaseBundle.java:1084) [关键行] at io.flutter.plugins.someplugin.NativeHandler.handleIntent(NativeHandler.java:47) ``` 箭头指示位置:`BaseBundle.java`的1084行尝试将Integer强制转为Long。 #### 预防措施 1. 在跨组件通信时统一使用`long`类型 2. 使用序列化框架(如ProtoBuf)替代直接传递基本类型 3. 在`AndroidManifest.xml`中声明明确的数据类型: ```xml <intent-filter> <data android:mimeType="application/vnd.long_value"/> </intent-filter> ``` > 该异常通常不影响Flutter界面渲染,但可能导致原生功能(如后台服务、广播接收器)异常。建议优先检查涉及Intent传递的插件代码[^1]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值