如何通过 PendingIntent 将自定义 Serializable 对象传递给 BroadcastReceiver [英] How to pass custom Serializable object to BroadcastReceiver via PendingIntent

查看:35
本文介绍了如何通过 PendingIntent 将自定义 Serializable 对象传递给 BroadcastReceiver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 PendingIntent 将自定义序列化对象从我的 IntentService 传递到 BroadcastReceiver.

I am trying to pass a custom Serialized object from my IntentService to a BroadcastReceiver using PendingIntent.

这是我的自定义对象:

行.java

public class Row implements Serializable {
    private String name;
    private String address;

    public Row(BluetoothDevice device) {
        this.name = device.getName();
        this.address = device.getAddress();
    }
}

这是我的 IntentService

Here is my IntentService

MyIntentService.java

MyIntentService.java

public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void onHandleIntent(Intent workIntent) {
        AlarmManager alarmMgr;
        PendingIntent alarmPendingIntent;
        Intent alarmIntent;
        // The object "RowsList" is passed from my MainActivity and is correctly received by my IntentService.
        // NO PROBLEMS HERE
        Row[] arrRows = (Row[])workIntent.getSerializableExtra("RowsList");

        Log.i(TAG, "Inside Intent Service...");

        int interval = 2;
        try{
            if(interval != 0) {
                alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
                alarmIntent = new Intent(this, AlarmReceiver.class);
                alarmIntent.putExtra("IntentReason", "Reason"); // THIS GETS PASSED
                alarmIntent.putExtra("RowsList", arrRows); // THIS DOES NOT GET PASSED
                alarmPendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

                alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + (interval * 1000), alarmPendingIntent);
                }
        }
        catch (Exception ignored){}
    }
}

MainActivity.java

MainActivity.java

// NO PROBLEMS HERE
private Intent myIntent;
myIntent = new Intent(getApplicationContext(), MyIntentService.class);
Log.i(TAG, "Starting Intent Service...");

myIntent.putExtra("RowsList", arrRows);
getApplicationContext().startService(intentListenBT);

这是我的广播接收器:

报警接收器.java

public class AlarmReceiver extends BroadcastReceiver {

    Row[] arrRows;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;
        String str = intent.getStringExtra("IntentReason"); // RECEIVED AS "Reason"
        arrRows = (Row[])intent.getSerializableExtra("RowsList"); // HERE IT IS null
    }
}

最烦人的部分是此代码以前在我的 Nexus 6P (Lollipop 6.0 API23) 上运行.一旦我将同一部手机更新到 Android 7.0(牛轧糖),它就停止工作了.Nougat 中是否有任何变化导致了这个问题?

The most annoying part is that this code was working previously on my Nexus 6P (Lollipop 6.0 API23). It stopped working once I updated the same phone to Android 7.0(Nougat). Is there anything that has changed in Nougat that is causing this problem?

注意:

我在带有 API 23 的 Nexus 6P 上使用模拟器运行了我的代码,并且运行良好.

I ran my code using an emulator on Nexus 6P with API 23 and it works fine.

推荐答案

很可能,您遇到了与使用 自定义Parcelable 实现.从那篇博文中转述我自己:基本上,如果核心操作系统进程需要修改 Intent 附加功能,该进程最终会尝试重新创建您的 Serializable 对象作为设置的一部分用于修改的附加 Bundle.该进程没有您的类,因此会出现运行时异常.

Most likely, you are running into the same sort of problem that you see with custom Parcelable implementations. Paraphrasing myself from that blog post: basically, if a core OS process needs to modify the Intent extras, that process winds up trying to recreate your Serializable objects as part of setting up the extras Bundle for modification. That process does not have your class and so it gets a runtime exception.

最烦人的部分是此代码以前在我的 Nexus 6P (Lollipop 6.0 API23) 上运行.

The most annoying part is that this code was working previously on my Nexus 6P (Lollipop 6.0 API23).

行为会因 Android 版本、您使用 PendingIntent 的方式以及固件/ROM 的不同而有所不同.不要假设您当前的实现在任何 Android 版本上都是可靠的.

The behavior will vary by Android version, by how you are using the PendingIntent, and possibly by firmware/ROM. Do not assume that your current implementation will be reliable on any Android version.

您唯一的选择是不要将 Serializable 直接放在 Intent 额外中.使用 Serializable 以外的东西(例如,嵌套的 Bundle),将 Serializable 转换为 byte[],等

Your only option is to not put the Serializable directly in an Intent extra. Use something other than Serializable (e.g., a nested Bundle), convert the Serializable into a byte[], etc.

这个示例应用演示了后一种方法, 应用于 Parcelable 对象.相同的基本技术应该适用于Serializable.(给 AyeVeeKay 的帽子提示以获取评论中的链接).

This sample app demonstrates the latter approach, applied to a Parcelable object. The same basic technique should work for Serializable. (hat tip to AyeVeeKay for the link in the comments).

这篇关于如何通过 PendingIntent 将自定义 Serializable 对象传递给 BroadcastReceiver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆