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

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

问题描述

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

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

这是我的自定义对象:

Row.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);

这是我的BroadcastReceiver:

Here is my BroadcastReceiver:

AlarmReceiver .java

AlarmReceiver.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),它就停止了工作。 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.

推荐答案

很可能,你遇到了同样的问题您在 custom中看到的问题 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天全站免登陆