Z tego przewodnika dowiesz się, jak zgłosić stan żądania roboczego uruchomionego w usłudze w tle do komponentu, który je wysłał. Dzięki temu możesz na przykład zgłosić stan żądania w interfejsie użytkownika obiektu Activity
. Zalecanym sposobem wysyłania i odbierania stanu jest użycie klasy LocalBroadcastManager
, która ogranicza przesyłanie obiektów Intent
do komponentów w Twojej aplikacji.
Raportuj stan z JobIntentService
Aby wysyłać stan żądania roboczego w JobIntentService
do innych komponentów, najpierw utwórz obiekt Intent
zawierający stan w jego rozszerzonych danych. Możesz też dodać działanie i identyfikator URI danych do tego zasobu Intent
.
Następnie wyślij Intent
, dzwoniąc pod numer LocalBroadcastManager.sendBroadcast()
. Spowoduje to wysłanie żądania Intent
do dowolnego komponentu w aplikacji, który zarejestrował się w celu jego otrzymania.
Aby pobrać instancję LocalBroadcastManager
, wywołaj getInstance()
.
Na przykład:
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); ... }
Następnym krokiem jest obsługa przychodzących obiektów Intent
w komponencie, który wysłał pierwotne żądanie robocze.
Odbieranie komunikatów o stanie z usługi JobIntentService
Aby odbierać transmitowane obiekty Intent
, użyj podklasy BroadcastReceiver
. W podklasie zaimplementuj metodę wywołania zwrotnego BroadcastReceiver.onReceive()
, która jest wywoływana przez LocalBroadcastManager
, gdy otrzyma Intent
. LocalBroadcastManager
przekazuje przychodzące dane Intent
do BroadcastReceiver.onReceive()
.
Na przykład:
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. */ ... } }
Po zdefiniowaniu atrybutu BroadcastReceiver
możesz zdefiniować dla niego filtry pasujące do określonych działań, kategorii i danych. Aby to zrobić, utwórz IntentFilter
. Pierwszy fragment kodu pokazuje, jak zdefiniować filtr:
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"); ...
Aby zarejestrować w systemie BroadcastReceiver
i IntentFilter
, pobierz instancję LocalBroadcastManager
i wywołaj jej metodę registerReceiver()
. Z tego fragmentu dowiesz się, jak zarejestrować komponent BroadcastReceiver
i jego 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); ...
Jeden obiekt BroadcastReceiver
może obsłużyć więcej niż 1 typ obiektu przesyłania Intent
, z którym każdy może mieć swoje własne działanie. Ta funkcja pozwala uruchamiać inny kod dla każdego działania bez konieczności definiowania osobnego kodu BroadcastReceiver
dla każdego działania. Aby zdefiniować kolejny IntentFilter
dla tego samego elementu BroadcastReceiver
, utwórz IntentFilter
i powtórz wywołanie registerReceiver()
.
Na przykład:
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);
Wysłanie transmisji Intent
nie powoduje rozpoczęcia ani wznowienia
Activity
. Pole BroadcastReceiver
dla Activity
odbiera i przetwarza obiekty Intent
nawet wtedy, gdy aplikacja działa w tle, ale nie wymusza przeniesienia aplikacji na pierwszy plan. Jeśli chcesz powiadomić użytkownika o zdarzeniu, które miało miejsce w tle, gdy Twoja aplikacja nie była widoczna, użyj Notification
. Nigdy nie uruchamiaj metody Activity
w odpowiedzi na przychodzącą transmisję Intent
.