The past couple weeks I've been learning some Android development using Android Studio and Java. I'm making a basic RSS notifier which requires some background processing every X minutes (to check the tracked RSS feeds).

I'm using something like the custom AlarmReceiver shown below to handle the application being woken up.

public class FeedUpdaterAlarmReceiver extends WakefulBroadcastReceiver {

    public static final int REQUEST_CODE = 87126;
    public static final String ACTION = "me.isaacjordan.rsstracker.feedupdateralarm";

    // Triggered by the Alarm periodically (starts the service to run task)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ACTION)) {
            Log.d("FeedUpdaterAlarmRecv", "Action was correct.");
        } else {
            Log.d("FeedUpdaterAlarmRecv", "Action was not correct!");
            return;
        }

        TrackedFeed trackedFeed = intent.getParcelableExtra("trackedFeed");
        Intent i = new Intent(context, FeedUpdaterService.class);
        i.putExtra("trackedFeed", trackedFeed);
        context.startService(i);
    }
}

This then starts the service that actually checks the feed for new posts. However, I ran in to the issue that my `trackedFeed` was always null. I checked the documentation, checked examples, tried several other forms of passing my TrackedFeed object - however it was still null.

I came across a StackOverflow post that showed a technique that appeared to work. It involves converting the custom Parcelable object to a byte array (byte[]), passing this byte array through the Android Intent, and then converting the byte array back to the Parcelable object. 

The first piece of code required is a utility class to convert a Parcelable class to a byte[]. This is always possible since the point of Parcelable is to indicate the class is serializable in some specific way. All credit for this class goes to Flow on SO.

public class ParcelableUtil {
    public static byte[] marshall(Parcelable parceable) {
        Parcel parcel = Parcel.obtain();
        parceable.writeToParcel(parcel, 0);
        byte[] bytes = parcel.marshall();
        parcel.recycle();
        return bytes;
    }

    public static Parcel unmarshall(byte[] bytes) {
        Parcel parcel = Parcel.obtain();
        parcel.unmarshall(bytes, 0, bytes.length);
        parcel.setDataPosition(0); // This is extremely important!
        return parcel;
    }

    public static <T> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) {
        Parcel parcel = unmarshall(bytes);
        T result = creator.createFromParcel(parcel);
        parcel.recycle();
        return result;
    }
}

Next we modify our AlarmReceiver to make use of this, as follows.

public class FeedUpdaterAlarmReceiver extends WakefulBroadcastReceiver {

    public static final int REQUEST_CODE = 87126;
    public static final String ACTION = "me.isaacjordan.rsstracker.feedupdateralarm";

    // Triggered by the Alarm periodically (starts the service to run task)
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ACTION)) {
            Log.d("FeedUpdaterAlarmRecv", "Action was correct.");
        } else {
            Log.d("FeedUpdaterAlarmRecv", "Action was not correct!");
        }

        byte[] bytes = intent.getByteArrayExtra("bytes");

        Intent i = new Intent(context, FeedUpdaterService.class);
        i.putExtra("bytes", bytes);
        context.startService(i);
    }
}

The creation and consumption of the byte[] is as follows:

byte[] bytes = ParcelableUtil.marshall(trackedFeed);
intent.putExtra("bytes", bytes);

// Later
byte[] bytes = intent.getByteArrayExtra("bytes");
TrackedFeed tf = new TrackedFeed(ParcelableUtil.unmarshall(bytes));

Just replace `TrackedFeed` with your own Parcelable class in order to pass objects across an AlarmReceiver in Android! No more null references.


Check out my other blog posts! If you found this post interesting, feel free to let me know either on Twitter (@Isaac_M_Jordan), or in the comments section below.

Enjoyed my post? Sign up to the newsletter to receive a small email when I post. No spam, I promise.