標籤:
原文地址:https://developer.android.com/training/run-background-service/report-status.html
這節課主要學習如何將IntentService中的執行結果返回給請求點。一種推薦的方式就是使用 LocalBroadcastManager來實現,它會將所廣播的Intent限制在APP內部。
發送IntentService的處理結果
為了可以將IntentService的處理結果發送給其它組件,首先需要建立一個Intent對象,並將執行結果放入該Intent內。
接下來要做的就是:將剛才建立好的Intent通過LocalBroadcastManager.sendBroadcast()發送出去。但凡是對該Intent註冊了的,那麼發送該Intent都會收到結果。可以通過getInstance()擷取LocalBroadcastManager的執行個體。
例子如下:
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 IntentService {... /* * 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);...}
下一步就是如何處理接收到的Intent對象了。
接收IntentService的處理結果
如果需要接收廣播出來的Intent,那麼就需要用到BroadcastReceiver了。在BroadcastReceiver的實作類別中重寫onReceive()方法。當LocalBroadcastManager將相應的Intent對象廣播出來後,那麼該方法就會被自動回調。
舉個例子:
// Broadcast receiver for receiving status updates from the IntentServiceprivate class ResponseReceiver extends BroadcastReceiver{ // Prevents instantiation private DownloadStateReceiver() { } // Called when the BroadcastReceiver gets an Intent it‘s registered to receive @ public void onReceive(Context context, Intent intent) {... /* * Handle Intents here. */... }}
一旦定義好了BroadcastReceiver,那麼就可以為其定義指定的意圖過濾器了。要做到這些,需要建立一個IntentFilter。下面的代碼示範了如何定義一個過濾器:
// Class that displays photospublic class DisplayActivity extends FragmentActivity { ... public void onCreate(Bundle stateBundle) { ... super.onCreate(stateBundle); ... // The filter‘s action is BROADCAST_ACTION IntentFilter mStatusIntentFilter = new IntentFilter( Constants.BROADCAST_ACTION); // Adds a data filter for the HTTP scheme mStatusIntentFilter.addDataScheme("http");
為了將BroadcastReceiver以及IntentFilter註冊到系統,需要先擷取LocalBroadcastManager的執行個體,然後再調用它的registerReceiver()方法。下面的代碼示範了這個過程:
// Instantiates a new DownloadStateReceiver DownloadStateReceiver mDownloadStateReceiver = new DownloadStateReceiver(); // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this).registerReceiver( mDownloadStateReceiver, mStatusIntentFilter); ...
BroadcastReceiver可以同時處理多種類型的Intent對象,這項特性可以為每種Action定義不同的代碼,而不需要專門去定義BroadcastReceiver。為同一個BroadcastReceiver定義另外的IntentFilter,只需再建立一個IntentFilter,然後再次註冊一下就好:
/* * 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(getActivity()).registerReceiver( mDownloadStateReceiver, mIntentFilter);
發送廣播Intent並不會啟動或者恢複Activity。就算是APP處於掛起狀態(處於後台)也同樣會接收到Intent。如果APP處於掛起狀態的話,有任務完成需要通知到使用者,那麼可以使用Notification做到。絕不要啟動Activity來響應接收到的Intent廣播。
Android官方開發文檔Training系列課程中文版:後台服務之響應IntentService的處理結果