如何通过PendingIntent将自定义Serializable对象传递给BroadcastReceiver [英] How to pass custom Serializable object to BroadcastReceiver via PendingIntent
问题描述
我正在尝试使用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屋!