梅明子 2016-08-26 03:13 采纳率: 100%
浏览 2273
已采纳

Android 序列化Intent对象到本地异常问题

        // 序列化PendingIntent对象,以时间作为文件名
        String fileName = String.valueOf(ent.date);
        PendingIntent intent = noti.contentIntent;

        L.e("recordNotification", "保存文件名:" + fileName);
        L.e("recordNotification", "PendingIntent:" + intent);
        ParcelableFileUtil.writeParcelable(mContext, fileName, intent);

        L.e("recordNotification", "保存通知并刷新界面");
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                NotificationWrapper.getInstance().addNotificationList(ent);
                NotificationWrapper.getInstance().refreshNotification();
            }
        };
        handler.post(runnable);

        // cancelNotification(packageName, sbn.getTag(), sbn.getId());

我这是从通知栏里获取到一个通知的Intent,然后我想把它序列化保存到本地,在方法writeParcelable中出现报错。但搞不懂不知为什么出错。

writeParcelable方法如下,执行到byte[] data = parcel.marshall();返回二进制字节这里就出下面那个错了。

     /**
     * 存储单个Parcelable对象
     * 
     * @param context
     * @param fileName
     * @param object
     * @return boolean
     */
    public static boolean writeParcelable(Context context, String fileName,
            Parcelable object) {
        if (fileName == null || object == null) {
            return false;
        }
        boolean success = false;
        FileOutputStream outPutStream = null;
        try {
            outPutStream = context.openFileOutput(fileName,
                    Context.MODE_PRIVATE);
            Parcel parcel = Parcel.obtain();
            parcel.writeParcelable(object,
                    Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
            byte[] data = parcel.marshall();
            outPutStream.write(data);
            success = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            success = false;
        } catch (IOException e) {
            e.printStackTrace();
            success = false;
        } finally {
            if (outPutStream != null) {
                try {
                    outPutStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return success;
    }

错误日志截图:
图片说明

错误日志代码:

     08-26 03:07:38.023: E/onNotificationPosted(11563): packageName:com.example.notifications
    08-26 03:07:38.043: E/recordNotification(11563): 系统通知View
    08-26 03:07:38.113: E/Util(11563): saveBitmap:/storage/emulated/0/CleanMaster/notification_cache/IMG_20160826030738
    08-26 03:07:38.113: E/recordNotification(11563): 保存文件名:1472180858021
    08-26 03:07:38.113: E/recordNotification(11563): PendingIntent:PendingIntent{4238f680: android.os.BinderProxy@42355f30}
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563): Error running onNotificationPosted
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563): java.lang.RuntimeException: Tried to marshall a Parcel that contained Binder objects.
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at android.os.Parcel.nativeMarshall(Native Method)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at android.os.Parcel.marshall(Parcel.java:420)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at com.qiulong.notificationintercepttest.util.ParcelableFileUtil.writeParcelable(ParcelableFileUtil.java:36)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at com.qiulong.notificationintercepttest.service.NotificationListener.getNotificationInfo(NotificationListener.java:125)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at com.qiulong.notificationintercepttest.service.NotificationListener.onNotificationPosted(NotificationListener.java:58)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at android.service.notification.NotificationListenerService$INotificationListenerWrapper.onNotificationPosted(NotificationListenerService.java:168)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at android.service.notification.INotificationListener$Stub.onTransact(INotificationListener.java:56)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at android.os.Binder.execTransact(Binder.java:404)
    08-26 03:07:38.113: W/NotificationListenerService[NotificationListener](11563):     at dalvik.system.NativeStart.run(Native Method)
  • 写回答

3条回答 默认 最新

  • FFZ2009 2016-08-26 08:34
    关注

    这个异常是说,parcel中含有Ibinder对象,因此Parcel中的数据不能被简单的序列化成字节流。
    这是由Parcel的设计和实现决定的。
    总的来说就是:使用Parcel.mashall把对象保存到本地文件是不允许的。
    Parcel的文档有这样的提示

    Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.

    大意是Parcel不是一般用途的序列化机制。这个类(和对应的Parcelable API )设计目的是作为一个高性能的IPC 数据传递机制。因此,不适合把任意的Parcel数据存到永久存储(比如本地文件)中:Parcel中的任何一种这样的数据的底层实现的改变会使老的数据不可读。

    另外Parcel.mashall的方法注释中提到

    The data you retrieve here** must no**t be placed in any kind of persistent storage (on local disk, across a network, etc). For that, you should use standard serialization or another kind of general serialization mechanism. The Parcel marshalled representation is highly optimized for local IPC, and as such does not attempt to maintain compatibility with data created in different versions of the platform.

    大意是从Parcel.mashall中得到的数据**不应该**被保存到任何一种永久存储中(例如,本地磁盘,跨网络)。 如果你想永久存储的话,需要用标准的的Serialization。Parcel 的marshall为本地IPC做了极大的优化,因此没有去维护数据的兼容性。

    要解决你碰到的异常就只能使用更为普通的序列化机制了。
    这里提供一个大概的思路就是用Java的 Serialization.
    当然Intent没有实现Serializable接口,这就得自己设计一个类,姑且叫SerializedIntent,实现Serializable接口,将你需要保存的属性作为成员放到SerializedIntent中,将SerializedIntent对象保存为本地文件。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 TMC2209串口模式下读取不到寄存器的值串口助手蓝色字体是发过去的消息,绿色字体是收到的消息,第二行发送读取寄存器的指令但是没有读取到寄存器的值串口助手如下图:接线如下图,如何解决?
  • ¥15 高通安卓11提取完整线刷包软件,或者优博讯dt50顺丰刷机包
  • ¥20 C,有个译码器,换了信道就跑不出原来数据
  • ¥15 MIMIC数据库安装问题
  • ¥60 基于JTag协议开发Fpga下载器上位机,哪位大🐂有偿指导?
  • ¥20 全书网Java爬取数据
  • ¥15 怎么获取红包封面的原始链接,并且获取红包封面序列号
  • ¥100 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏
  • ¥15 STM32串口接收问题