报告工作状态

本指南介绍了如何向发送请求的组件报告在后台服务中运行的工作请求的状态。例如,您可以在 Activity 对象的界面中报告请求的状态。发送和接收状态的推荐方法是使用 LocalBroadcastManager,它会将广播 Intent 对象限制为您自己应用中的组件。

从 JobIntentService 报告状态

如需将 JobIntentService 中的工作请求的状态发送到其他组件,请先创建一个 Intent,并在其扩展数据中包含该状态。您可以选择向此 Intent 添加操作和数据 URI。

接下来,通过调用 LocalBroadcastManager.sendBroadcast() 发送 Intent。这会将 Intent 发送到应用中已注册接收它的组件。 如需获取 LocalBroadcastManager 的实例,请调用 getInstance()

例如:

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);
...
}

下一步是处理发送原始工作请求的组件中的传入广播 Intent 对象。

接收来自 JobIntentService 的状态广播

如需接收广播 Intent 对象,请使用 BroadcastReceiver 的子类。在该子类中,实现 BroadcastReceiver.onReceive() 回调方法,LocalBroadcastManager 会在收到 Intent 时调用该方法。LocalBroadcastManager 将传入的 Intent 传递给 BroadcastReceiver.onReceive()

例如:

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.
         */
...
    }
}

定义 BroadcastReceiver 后,您便可以为其定义匹配特定操作、类别和数据的过滤器。为此,请创建一个 IntentFilter。第一个代码段展示了如何定义过滤器:

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");
        ...

如需向系统注册 BroadcastReceiverIntentFilter,请获取 LocalBroadcastManager 的实例并调用其 registerReceiver() 方法。接下来的这个代码段展示了如何注册 BroadcastReceiver 及其 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);
        ...

一个BroadcastReceiver可以处理多种类型的广播Intent对象,每种类型都有自己的操作。此功能允许您为每个操作运行不同的代码,而不必为每项操作定义单独的 BroadcastReceiver。如需为同一 BroadcastReceiver 定义另一个 IntentFilter,请创建 IntentFilter 并重复调用 registerReceiver()。 例如:

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);

发送广播 Intent 不会启动或恢复 Activity。即使应用位于后台,ActivityBroadcastReceiver 也会接收并处理 Intent 对象,但不会强制应用转到前台。如果您想通知用户您的应用不可见时后台发生的事件,请使用 Notification切勿启动 Activity 来响应传入的广播 Intent