问题
I am trying to pass a custom Serialized object from my IntentService to a BroadcastReceiver using PendingIntent.
Here is my custom object:
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();
}
}
Here is my IntentService
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
// 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);
Here is my BroadcastReceiver:
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
}
}
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?
NOTE:
I ran my code using an emulator on Nexus 6P with API 23 and it works fine.
回答1:
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.
The most annoying part is that this code was working previously on my Nexus 6P (Lollipop 6.0 API23).
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.
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.
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).
来源:https://stackoverflow.com/questions/39209579/how-to-pass-custom-serializable-object-to-broadcastreceiver-via-pendingintent