Questa guida mostra come segnalare lo stato di una richiesta di lavoro eseguita in un servizio in background
al componente che ha inviato la richiesta. Ciò ti consente, ad esempio, di segnalare lo stato
la richiesta nella UI di un oggetto Activity
. Il metodo consigliato per inviare e
ricevi lo stato consiste nell'utilizzare un LocalBroadcastManager
, che
limita la trasmissione di Intent
oggetti ai componenti della tua app.
Segnala lo stato da un JobIntentService
Per inviare lo stato di una richiesta di lavoro in un
JobIntentService
ad altro
componenti, occorre prima creare un Intent
che contenga lo stato nel
dati estesi. Se vuoi, puoi aggiungere un URI di azione e dati
Intent
.
Dopodiché, invia Intent
chiamando
LocalBroadcastManager.sendBroadcast()
. L'elemento Intent
viene inviato a qualsiasi
dell'applicazione che si è registrato per riceverlo.
Per ottenere un'istanza di LocalBroadcastManager
, chiama
getInstance()
.
Ad esempio:
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); ... }
Il passaggio successivo prevede la gestione degli oggetti Intent
di broadcast in arrivo
il componente che ha inviato la richiesta di lavoro originale.
Ricevi trasmissioni di stato da un JobIntentService
Per ricevere oggetti Intent
broadcast, utilizza una sottoclasse
BroadcastReceiver
. Nella sottoclasse, implementa
Chiamata di BroadcastReceiver.onReceive()
che LocalBroadcastManager
richiama quando riceve
un Intent
. LocalBroadcastManager
passa il Intent
in arrivo a
BroadcastReceiver.onReceive()
.
Ad esempio:
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. */ ... } }
Dopo aver definito l'BroadcastReceiver
, puoi definire i filtri
che corrispondono ad azioni, categorie e dati specifici. A questo scopo, crea
IntentFilter
. Questo primo snippet mostra come definire il filtro:
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"); ...
Per registrare il BroadcastReceiver
e il
IntentFilter
con il sistema, ottieni un'istanza
LocalBroadcastManager
e li chiami
registerReceiver()
. Il prossimo snippet mostra come registrare il BroadcastReceiver
e le relative 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 singolo BroadcastReceiver
può gestire più di un tipo di oggetto broadcastingIntent
, ognuno con la propria azione. Questa funzione consente di
eseguire un codice diverso per ogni azione, senza dover definire
BroadcastReceiver
per ogni azione. Per definire un altro tipo di
IntentFilter
per lo stesso
BroadcastReceiver
, crea i IntentFilter
e
ripeti la chiamata a
registerReceiver()
.
Ad esempio:
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'invio di un broadcast Intent
non avvia o non riprende un
Activity
. BroadcastReceiver
per
Activity
riceve ed elabora Intent
oggetti anche
quando l'app è in background, ma non la forza in primo piano. Se
vuoi informare l'utente di un evento che si è verificato in background mentre la tua app non era
visibile, utilizza un Notification
. Non avviare mai
Activity
in risposta a una trasmissione in arrivo
Intent
.