简体   繁体   中英

Passing realm object to an pending intent of alarm manager

I am developing an alarm app and I am trying to pass the realm object to alarm manager for setting an alarm

Caused by: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = io.realm.AlarmRealmProxy) at android.os.Parcel.writeSerializable(Parcel.java:1527) at android.os.Parcel.writeValue(Parcel.java:1475) at android.os.Parcel.writeArrayMapInternal(Parcel.java:724) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1408) at android.os.Bundle.writeToParcel(Bundle.java:1157) at android.os.Parcel.writeBundle(Parcel.java:764) at android.content.Intent.writeToParcel(Intent.java:8687) at android.os.Parcel.writeTypedArray(Parcel.java:1307) at android.app.ActivityManagerProxy.getIntentSender(ActivityManagerNative.java:4653) at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:562) at android.app.PendingIntent.getBroadcast(PendingIntent.java:545) at in.kka.physiotherapy.model.Alarm.schedule(Alarm.java:143) at in.kka.physiotherapy.service.AlarmService.onStartCommand(AlarmService.java:99) at android.app.ActivityThread.handleServiceArgs(A ctivityThread.java:3326) at android.app.ActivityThread.-wrap21(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: java.io.NotSerializableException: io.realm.AlarmRealmProxy$AlarmColumnInfo at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1224) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1584) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1549) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1472) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1218) at java.io.O bjectOutputStream.writeObject(ObjectOutputStream.java:346) at android.os.Parcel.writeSerializable(Parcel.java:1522) at android.os.Parcel.writeValue(Parcel.java:1475) at android.os.Parcel.writeArrayMapInternal(Parcel.java:724) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1408) at android.os.Bundle.writeToParcel(Bundle.java:1157) at android.os.Parcel.writeBundle(Parcel.java:764) at android.content.Intent.writeToParcel(Intent.java:8687) at android.os.Parcel.writeTypedArray(Parcel.java:1307) at android.app.ActivityManagerProxy.getIntentSender(ActivityManagerNative.java:4653) at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:562) at android.app.PendingIntent.getBroadcast(PendingIntent.java:545) at in.kka.physiotherapy.model.Alarm.schedule(Alarm.java:143) at in.kka.physiotherapy.service.AlarmService.onStartCommand(AlarmService.java:99) at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3326) at android.app.ActivityThread.-wrap21(A ctivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Here is my code my class implements Serializable but i'm not able to pass intent extra, i am getting error here myIntent.putExtra("alarm", this);

public void schedule(Context context) {
        Realm  realm = Realm.getDefaultInstance();

        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                setAlarmActive(true);
            }
        });


        Intent myIntent = new Intent(context, AlarmServiceBroadcastReciever.class);
        myIntent.putExtra("alarm", this);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent,PendingIntent.FLAG_CANCEL_CURRENT);

        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        alarmManager.set(AlarmManager.RTC_WAKEUP, getAlarmTime().getTime(), pendingIntent);
    }

You're trying to pass a managed , "live" realm object, which is based by a proxy implementation - you need to pass a "detached" unmanaged object to the intent. Change this line:

myIntent.putExtra("alarm", this);

To this:

myIntent.putExtra("alarm", realm.copyFromRealm(this));

Also, you should close the Realm instance, preferably wrapping the transaction and copyFromRealm call in a try-catch block:

Realm realm = null;
try {
    realm = Realm.getDefaultInstance();
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm transactionRealm) {
            setAlarmActive(true);
        }
    });
    Intent myIntent = new Intent(context, AlarmServiceBroadcastReciever.class);
    myIntent.putExtra("alarm", realm.copyFromRealm(this));
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent,PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, getAlarmTime().getTime(), pendingIntent);
} finally {
    if(realm != null) {
        realm.close();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM