Ce guide explique comment signaler l'état d'une requête de tâche exécutée dans un service d'arrière-plan au composant qui a envoyé la requête. Cela vous permet, par exemple, de signaler l'état de la requête dans l'interface utilisateur d'un objet Activity
. La méthode recommandée pour envoyer et recevoir un état consiste à utiliser un LocalBroadcastManager
, ce qui limite les objets Intent
de diffusion aux composants de votre propre application.
État du rapport à partir d'un JobIntentService
Pour envoyer l'état d'une requête de tâche dans un JobIntentService
à d'autres composants, créez d'abord un Intent
contenant l'état dans ses données étendues. Si vous le souhaitez, vous pouvez ajouter une action et un URI de données à ce Intent
.
Envoyez ensuite Intent
en appelant LocalBroadcastManager.sendBroadcast()
. Cette opération envoie le Intent
à n'importe quel composant de votre application qui s'est enregistré pour le recevoir.
Pour obtenir une instance de LocalBroadcastManager
, appelez getInstance()
.
Par exemple :
Kotlin
... // Defines a custom Intent action const val BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST" ... // Defines the key for the status "extra" in an Intent const val EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS" ... class RSSPullService : JobIntentService() { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ val localIntent = Intent(BROADCAST_ACTION).apply { // Puts the status into the Intent putExtra(EXTENDED_DATA_STATUS, status) } // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent) ... }
Java
public final class Constants { ... // Defines a custom Intent action public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST"; ... // Defines the key for the status "extra" in an Intent public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS"; ... } public class RSSPullService extends JobIntentService { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ Intent localIntent = new Intent(Constants.BROADCAST_ACTION) // Puts the status into the Intent .putExtra(Constants.EXTENDED_DATA_STATUS, status); // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); ... }
L'étape suivante consiste à gérer les objets de diffusion Intent
entrants dans le composant qui a envoyé la requête de travail d'origine.
Recevoir des annonces d'état d'un JobIntentService
Pour recevoir des objets de diffusion Intent
, utilisez une sous-classe de BroadcastReceiver
. Dans la sous-classe, implémentez la méthode de rappel BroadcastReceiver.onReceive()
, que LocalBroadcastManager
appelle lorsqu'elle reçoit une Intent
. LocalBroadcastManager
transmet le Intent
entrant à BroadcastReceiver.onReceive()
.
Par exemple :
Kotlin
// Broadcast receiver for receiving status updates from the IntentService. private class DownloadStateReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { ... /* * Handle Intents here. */ ... } }
Java
// Broadcast receiver for receiving status updates from the IntentService. private class DownloadStateReceiver extends BroadcastReceiver { // Called when the BroadcastReceiver gets an Intent it's registered to receive @Override public void onReceive(Context context, Intent intent) { ... /* * Handle Intents here. */ ... } }
Une fois que vous avez défini l'élément BroadcastReceiver
, vous pouvez définir des filtres qui correspondent à des actions, des catégories et des données spécifiques. Pour ce faire, créez un IntentFilter
. Le premier extrait montre comment définir le filtre:
Kotlin
// Class that displays photos class DisplayActivity : FragmentActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... super.onCreate(savedInstanceState) ... // The filter's action is BROADCAST_ACTION var statusIntentFilter = IntentFilter(BROADCAST_ACTION).apply { // Adds a data filter for the HTTP scheme addDataScheme("http") } ...
Java
// Class that displays photos public class DisplayActivity extends FragmentActivity { ... public void onCreate(Bundle stateBundle) { ... super.onCreate(stateBundle); ... // The filter's action is BROADCAST_ACTION IntentFilter statusIntentFilter = new IntentFilter( Constants.BROADCAST_ACTION); // Adds a data filter for the HTTP scheme statusIntentFilter.addDataScheme("http"); ...
Pour enregistrer BroadcastReceiver
et IntentFilter
auprès du système, obtenez une instance de LocalBroadcastManager
et appelez sa méthode registerReceiver()
. L'extrait suivant montre comment enregistrer BroadcastReceiver
et son IntentFilter
:
Kotlin
// Instantiates a new DownloadStateReceiver val downloadStateReceiver = DownloadStateReceiver() // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this) .registerReceiver(downloadStateReceiver, statusIntentFilter) ...
Java
// Instantiates a new DownloadStateReceiver DownloadStateReceiver downloadStateReceiver = new DownloadStateReceiver(); // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this).registerReceiver( downloadStateReceiver, statusIntentFilter); ...
Un seul élément BroadcastReceiver
peut gérer plusieurs types d'objets Intent
de diffusion, chacun ayant sa propre action. Cette fonctionnalité vous permet d'exécuter un code différent pour chaque action, sans avoir à définir un BroadcastReceiver
distinct pour chaque action. Pour définir un autre IntentFilter
pour le même BroadcastReceiver
, créez le IntentFilter
et répétez l'appel de registerReceiver()
.
Par exemple :
Kotlin
/* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = IntentFilter(ACTION_ZOOM_IMAGE) // Registers the receiver with the new filter LocalBroadcastManager.getInstance(this) .registerReceiver(downloadStateReceiver, statusIntentFilter)
Java
/* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE); // Registers the receiver with the new filter LocalBroadcastManager.getInstance(this).registerReceiver( downloadStateReceiver, statusIntentFilter);
L'envoi d'une annonce Intent
ne démarre pas et ne reprend pas de Activity
. Le BroadcastReceiver
d'une Activity
reçoit et traite les objets Intent
même lorsque votre application est en arrière-plan, mais ne la force pas au premier plan. Si vous souhaitez informer l'utilisateur d'un événement qui s'est produit en arrière-plan alors que votre application n'était pas visible, utilisez un Notification
. Ne lancez jamais de Activity
en réponse à une annonce Intent
entrante.