Training—Running in a Background Service

阅读:http://developer.android.com/training/run-background-service/index.html

 

The IntentService class provides a straightforward structure for running an operation on a single background thread. This allows it to handle long-running operations without affecting your user interface's responsiveness. Also, an IntentService isn't affected by most user interface lifecycle events, so it continues to run in circumstances that would shut down an AsyncTask

An IntentService has a few limitations:

  • It can't interact directly with your user interface. To put its results in the UI, you have to send them to an Activity.
  • Work requests run sequentially. If an operation is running in an IntentService, and you send it another request, the request waits until the first operation is finished.
  • An operation running on an IntentService can't be interrupted.

However, in most cases an IntentService is the preferred way to simple background operations.

  IntentService拥有自己的一个线程,但是它有相对的限制:

  1、不能处理UI,因为UI控制必须在UI线程;

  2、你传递给他的认识将会排成队列一个个来,也就是说串行运行,一个任务直到运行完了才运行下个任务;

  3、无法被打断;

  

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

a simple example,就是你用intent启动的时候它去获取数据并且开始做事情。

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name">
        ...
        <!--
            Because android:exported is set to "false",
            the service is only available to this app.
        -->
        <service
            android:name=".RSSPullService"
            android:exported="false"/>
        ...
    <application/>

声明。要注意这里并没有过滤器,这意味着,只有本程序能调用这个service。

调用它吧:

/*
 * Creates a new Intent to start the RSSPullService
 * IntentService. Passes a URI in the
 * Intent's "data" field.
 */
mServiceIntent = new Intent(getActivity(), RSSPullService.class);
mServiceIntent.setData(Uri.parse(dataUrl));

// Starts the IntentService
getActivity().startService(mServiceIntent);

启动了它,当然要在它的运行过程中获取它的相关信息。

To send the status of a work request in an IntentService to other components, first create an Intent that contains the status in its extended data. As an option, you can add an action and data URI to this Intent.

Next, send the Intent by calling LocalBroadcastManager.sendBroadcast(). This sends the Intent to any component in your application that has registered to receive it. To get an instance of LocalBroadcastManager, call getInstance().

  通过intent来发送状态,然后使用 LocalBroadcastManager.sendBroadcast()来发送给所有已经注册了的组件(- -跟设计模式一模一样嘛)。

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

然后接下来你就写一个继承BroadcastReceiver的类去接受intent。而上面所提到的注册就是声明一个过滤器来获取广播了,例如:

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

     // Instantiates a new DownloadStateReceiver
        DownloadStateReceiver mDownloadStateReceiver =
                new DownloadStateReceiver();
        // Registers the DownloadStateReceiver and its intent filters
        LocalBroadcastManager.getInstance(this).registerReceiver(
                mDownloadStateReceiver,
                mStatusIntentFilter);
        ...

动态绑定intent和receiver。

A single BroadcastReceiver can handle more than one type of broadcast Intent object, each with its own action. This feature allows you to run different code for each action, without having to define a separate BroadcastReceiver for each action. To define another IntentFilter for the same BroadcastReceiver, create the IntentFilter and repeat the call to registerReceiver(). For example:

  当然,一个receiver是可以绑定多个intent的。

Sending an broadcast Intent doesn't start or resume an Activity. The BroadcastReceiver for an Activity receives and processes Intent objects even when your app is in the background, but doesn't force your app to the foreground. If you want to notify the user about an event that happened in the background while your app was not visible, use a Notification. Never start an Activity in response to an incoming broadcast Intent.

  请注意service的intent并不会启动activity,你也不应该启动或者强迫activity到前台,如果你需要传递信息,使用Notification。

posted @ 2013-11-09 10:45  yutoulck  阅读(271)  评论(0编辑  收藏  举报