本節(jié)講運(yùn)行在后臺(tái)服務(wù)里的工作請(qǐng)求,如何向發(fā)送請(qǐng)求者報(bào)告狀態(tài)。推薦用LocalBroadcastManager發(fā)送和接收狀態(tài),它限制了只有本app才能接收到廣播。
從IntentService匯報(bào)狀態(tài)
從IntentService發(fā)送工作請(qǐng)求狀態(tài)給其他組件,先創(chuàng)建一個(gè)包含狀態(tài)和數(shù)據(jù)的Intent。也可以添加action和URI到intent里。
下一步,調(diào)用 LocalBroadcastManager.sendBroadcast()發(fā)送Intent,應(yīng)用中所有注冊(cè)了接收該廣播的接收器都能收到。LocalBroadcastManager.getInstance()獲取LocalBroadcastManager實(shí)例。
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);
...
}
下一步是接收廣播并處理。
接收來(lái)自IntentService的廣播
接收方式與普通的Broadcast一樣,用一個(gè)BroadcastReceiver的子類(lèi),實(shí)現(xiàn)BroadcastReceiver.onReceive()方法
// Broadcast receiver for receiving status updates from the IntentService
private 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.
*/
...
}
}
定義好了接收器類(lèi)以后,定義過(guò)濾器,匹配指定的action,categorie,data.
// 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 mStatusIntentFilter = new IntentFilter(
Constants.BROADCAST_ACTION);
// Adds a data filter for the HTTP scheme
mStatusIntentFilter.addDataScheme("http");
...
注冊(cè)方式稍有不同,用LocalBroadcastManager.registerReceiver()。
// Instantiates a new DownloadStateReceiver
DownloadStateReceiver mDownloadStateReceiver =
new DownloadStateReceiver();
// Registers the DownloadStateReceiver and its intent filters
LocalBroadcastManager.getInstance(this).registerReceiver(
mDownloadStateReceiver,
mStatusIntentFilter);
...
單個(gè)BroadcastReceiver可以處理多種類(lèi)型的廣播,這個(gè)特性允許你根據(jù)不同的action運(yùn)行不同的代碼,而無(wú)需為每個(gè)action定義一個(gè)BroadcastReceiver。
/*
* 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);
發(fā)送廣播并不會(huì)啟動(dòng)或恢復(fù)Activity.BroadcastReceiver讓Activity能夠接收處理數(shù)據(jù),包括應(yīng)用在后臺(tái)的時(shí)候,但不會(huì)強(qiáng)制app回到前臺(tái)。如果你要在app在后臺(tái),對(duì)用戶(hù)不可見(jiàn)時(shí),通知用戶(hù)一個(gè)事件發(fā)生,用Notification。絕對(duì)不要啟動(dòng)一個(gè)Activity來(lái)響應(yīng)廣播。