使用IntentService执行后台任务

1、创建 IntentService

public class RSSPullService extends IntentService {
    @Override
    protected void onHandleIntent(Intent workIntent) {
        // Gets data from the incoming Intent
        String dataString = workIntent.getDataString();
        ...
        // Do work here, based on the contents of dataString
        ...
    }
}
<service
        android:name=".RSSPullService"
        android:exported="false"/>

2、使用 IntentService

mServiceIntent = new Intent(getActivity(), RSSPullService.class);
mServiceIntent.setData(Uri.parse(dataUrl));
// Starts the IntentService
getActivity().startService(mServiceIntent);

3、利用 IntentService 发送任务状态

为了在 IntentService 中向其他组件发送任务状态,首先创建一个 Intent 并在 data 字段中包含需要传递的信息。作为一个可选项,还可以给这个 Intent 添加一个 action 与 data URI。

下一步,通过执行 LocalBroadcastManager.sendBroadcast() 来发送 Intent。Intent 被发送到任何有注册接受它的组件中。为了获取到 LocalBroadcastManager 的实例,可以执行 getInstance()。代码示例如下:

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

下一步是在发送任务的组件中接收发送出来的 broadcast 数据。

4、接收来自 IntentService 的状态广播

为了接受广播的数据对象,需要使用 BroadcastReceiver 的子类并实现BroadcastReceiver.onReceive() 的方法,这里可以接收 LocalBroadcastManager 发出的广播数据。

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

一旦定义了 BroadcastReceiver,也应该定义 actions,categories 与 data 用过滤广播。为了实现这些,需要使用 IntentFilter。如下所示:

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

为了给系统注册这个 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 可以处理多种类型的广播数据。每个广播数据都有自己的 ACTION。这个功能使得不用定义多个不同的 BroadcastReceiver 来分别处理不同的 ACTION 数据。为 BroadcastReceiver 定义另外一个 IntentFilter,只需要创建一个新的 IntentFilter 并重复执行 registerReceiver() 即可。例如:

/*
 * 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 在后台运行,Activity 的 BroadcastReceiver 也可以接收、处理 Intent 对象。但是这不会迫使你的 app 进入前台。当你的 app 不可见时,如果想通知用户一个发生在后台的事件,建议使用 Notification。永远不要为了响应一个广播 Intent 而去启动 Activity。

你可能感兴趣的:(使用IntentService执行后台任务)