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

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 想问一下stata17中这段代码哪里有问题呀
  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决