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

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条)

报告相同问题?

悬赏问题

  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型