3.报告工作状态
这里将讲述如何将运行于后台服务的工作请求的结果状态报告给发送该请求的组件,例如:这里允许您发送请求结果状态给UI 对象中的某个Activity, 发送和接收结果状态推荐使用LocalBroadcastManager,这样限制了广播的Intent对象组件在您自己的应用中。
a. 来自IntentService 的报告状态
为了发送在一个IntentService中的工作请求结果状态给其他组件,首先创建一个在扩展数据域中包含这状态的Intent, 作为一个可选项,您可以添加一个action 和一个data URI 给这Intent。之后调用LocalBroadcastManager.sendBroadcast() 发送这个Intent,发送这Intent 给您应用中已经注册接收它的任意组件。为得到LocalBroadcastManager的实例,调用getInstance().
例如:
/**
*
* Constants used by multiple classes in this package
*/
public final class Constants {
// Set to true to turn on verbose logging
public static final boolean LOGV = false;
// Set to true to turn on debug logging
public static final boolean LOGD = true;
... ...
// 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广播对象。
b.接收来自IntenService的状态广播
使用BroadcastReceiver子类接收Intent 对象,在子类中实现BroadcastReceiver.onReceive() 回调方法,当接收一个Intent的时候,LocalBroadcastManager 调用并传递这传入的Intent 给BroadcastReceiver.onReceive()。
例如:
/ /**
* This class uses the BroadcastReceiver framework to detect and handle status messages from
* the service that downloads URLs.
*/
private class DownloadStateReceiver 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, 您可以给它定义过滤器(filters)创建一个IntentFilter,匹配指定的actions,categories 和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");
...
}
获取一个LocalBroadcastManager 实例,调用registerReceiver()方法,注册BroadcastReceiver 和IntentFilter。
/**
* This activity displays Picasa's current featured images. It uses a service running
* a background thread to download Picasa's "featured image" RSS feed.
* <p>
* An IntentHandler is used to communicate between the active Fragment and this
* activity. This pattern simulates some of the communication used between
* activities, and allows this activity to make choices of how to manage the
* fragments.
*/
public class DisplayActivity extends FragmentActivity implements OnBackStackChangedListener {
... ...
... ...
// Instantiates a new DownloadStateReceiver
DownloadStateReceiver mDownloadStateReceiver =
new DownloadStateReceiver();This first snippe
// Registers the DownloadStateReceiver and its intent filters
LocalBroadcastManager.getInstance(this).registerReceiver(
mDownloadStateReceiver,
mStatusIntentFilter);
... ...
... ...
}
单个BroadcastReceiver 可以处理多个类型的Intent 对象,每一个有它们自己的action,这样允许您根据不同的action执行不同的代码,为了给同一个BroadcastReceiver定义又一个IntentFilter,创建这个Interfilter, 重复调用registerReceiver(). 例如:
public class DisplayActivity extends FragmentActivity implements OnBackStackChangedListener {
... ...
... ...
// Creates a second filter for ACTION_ZOOM_IMAGE
displayerIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
// Registers the receiver
LocalBroadcastManager.getInstance(this).registerReceiver(
mFragmentDisplayer,
displayerIntentFilter);
... ...
... ...
}
发送一个Intent广播不会start或者resume 一个Activity,即使您的应用在后台,Activity的BroadcastReceiver能接收和处理Intent 对象, 但不会强制您的应用到前台,当应用在后台不可见发生一个事件,如果您想通知事件给用户, 使用Notification ,从来不会启动一个Activity 响应一个传入的Intent广播。