Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use "goAsync" for broadcastReceiver?

Background

Starting with Honeycomb (API 11) , Android has a feature to allow the broadcastReceiver run in an async way, providing it about 10 seconds before it assumes it can kill its process, using a method called "goAsync" :

This can be called by an application in onReceive(Context, Intent) to allow it to keep the broadcast active after returning from that function. This does not change the expectation of being relatively responsive to the broadcast (finishing it within 10s), but does allow the implementation to move work related to it over to another thread to avoid glitching the main UI thread due to disk IO.

The problem

I've searched in many places and didn't find any sample or tutorial of how to use it.

Not only that, but the method returns a PendingIntent instance which I'm not sure what to do with it:

Returns a BroadcastReceiver.PendingResult representing the result of the active broadcast. The BroadcastRecord itself is no longer active; all data and other interaction must go through BroadcastReceiver.PendingResult APIs. The PendingResult.finish() method must be called once processing of the broadcast is done.

The question

How do you use this method?

What is the PendingIntent that is returned by it, and what should I do with it?

like image 942
android developer Avatar asked Mar 30 '14 06:03

android developer


People also ask

How do you shoot in BroadcastReceiver?

inject(this, context); in onReceive method. class MyReceiver : DaggerBroadcastReceiver() { @Inject lateinit var repository: MyRepository override fun onReceive(context: Context?, intent: Intent?) { super. onReceive(context, intent) // Do your stuff... } }

What is the role of the onReceive () method in the BroadcastReceiver?

Retrieve the current result extra data, as set by the previous receiver. This can be called by an application in onReceive(Context, Intent) to allow it to keep the broadcast active after returning from that function.

What file is used to register the BroadcastReceiver?

An application listens for specific broadcast intents by registering a broadcast receiver in AndroidManifest. xml file. Consider we are going to register MyReceiver for system generated event ACTION_BOOT_COMPLETED which is fired by the system once the Android system has completed the boot process.

How do I send data from BroadcastReceiver to activity?

Intent intent = getIntent(); String message = intent. getStringExtra("message"); And then you will use message as you need. If you simply want the ReceiveText activity to show the message as a dialog, declare <activity android:theme="@android:style/Theme.


2 Answers

You can find short explanation here.

Use goAsync() if you want to handoff the processing inside of your BroadcastReceiver's onReceive() method to another thread. The onReceive() method can then be finished there. The PendingResult is passed to the new thread and you have to call PendingResult.finish() to actually inform the system that this receiver can be recycled.

For example:

final PendingResult result = goAsync();
Thread thread = new Thread() {
   public void run() {
      int i;
      // Do processing
      result.setResultCode(i);
      result.finish();
   }
};
thread.start();
like image 200
Broatian Avatar answered Oct 21 '22 11:10

Broatian


In kotlin you can write an extension function on BroadcastReceiver:

/**
 * Run work asynchronously from a [BroadcastReceiver].
 */
fun BroadcastReceiver.goAsync(
    coroutineScope: CoroutineScope,
    dispatcher: CoroutineDispatcher,
    block: suspend () -> Unit
) {
    val pendingResult = goAsync()
    coroutineScope.launch(dispatcher) {
        block()
        pendingResult.finish()
    }
}

After that inside your broadcast receiver you can do the following:

class AlarmBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        // Code here runs on the main thread

        goAsync(GlobalScope, Dispatchers.Default) {
            // The code here will run on the background by the default dispatcher on the global scope
            // If your code here touches the IO, then you can use Dispatchers.IO instead
        }
    }
like image 32
Mahmoud Avatar answered Oct 21 '22 11:10

Mahmoud