gaurav jain
gaurav jain

Reputation: 3234

Confusion about WakefulBroadcastReceiver

I've been studying WakefulBroadcastReceiver from this link : https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html

I have few confusions regarding this:

  1. Does this receiver ensures that you'll receive the broadcast even when the device is in sleep mode? (I think no, it just keeps the device awake after receiving the broadcast until a call to completeWakefulIntent() is made.)
  2. The documentation illustrates the use of intent service within the receiver and after the completion of work, a call to completeWakefulIntent is made.

CODE :

import android.app.IntentService;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;

public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.  This sample just does some slow work,
        // but more complicated implementations could take their own wake
        // lock here before releasing the receiver's.
        //
        // Note that when using this approach you should be aware that if your
        // service gets killed and restarted while in the middle of such work
        // (so the Intent gets re-delivered to perform the work again), it will
        // at that point no longer be holding a wake lock since we are depending
        // on SimpleWakefulReceiver to that for us.  If this is a concern, you can
        // acquire a separate wake lock here.
        for (int i=0; i<5; i++) {
            Log.i("SimpleWakefulReceiver", "Running service " + (i+1)
                    + "/5 @ " + SystemClock.elapsedRealtime());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
        }
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }
}

Now, as the docs say that this receiver holds a wake lock, I highly doubt that it's a good practice to start something like an intent service from the receiver. This would prevent the receiver from releasing the wake lock and drain a lot of battery as services are generally used for long operations.

Even as the code snippet above highlights, there's a delay of 25 seconds before releasing the lock. Is this the right way to use this receiver or should it be used only for short operations? Any help is appreciated.

Upvotes: 1

Views: 5271

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006724

Does this receiver ensures that you'll receive the broadcast even when the device is in sleep mode?

No.

(I think no, it just keeps the device awake after receiving the broadcast until a call to completeWakefulIntent() is made.)

Correct.

I highly doubt that it's a good practice to start something like an intent service from the receiver

Yes, it is a good practice. That's the entire point.

This would prevent the receiver from releasing the wake lock

The wake lock is held in a static data member, which is why a static method (completeWakefulWork()) is able to release it.

as services are generally used for long operations

The definition of "long" varies. I start using WakefulBroadcastReceiver (or my WakefulIntentService predecessor) for anything that is likely to exceed 10 seconds. However, an IntentService of any form is really only designed for transactional work (e.g., downloading a large file), and so it is not well-suited for cases where the service might need to run indefinitely (e.g., as long as the user wants to talk to a certain chat server).

You only use WakefulBroadcastReceiver when you want to ensure that the CPU will stay alive for the service to complete its work. Otherwise, you use the IntentService directly.

Is this the right way to use this receiver or should it be used only for short operations?

25 seconds is a perfectly reasonable time frame for using WakefulBroadcastReceiver and its associated IntentService.

but more complicated implementations could take their own wake lock here before releasing the receiver's

Sure, though it is unclear what this would gain you. A wake lock is a wake lock. A service-owned wake lock will have the exact same impact on battery as will a receiver-owned wake lock.

Upvotes: 10

Related Questions