IntentService簡介

銳湃發表於2015-09-07
 IntentService是Service類的子類,用來處理非同步請求。客戶端可以通過startService(Intent)方法傳遞請求給IntentServiceIntentServiceonCreate()函式中通過HandlerThread單獨開啟一個執行緒來處理所有Intent請求物件(通過startService的方式傳送過來的)所對應的任務,這樣以免事務處理阻塞主執行緒。執行完所一個Intent請求物件所對應的工作之後,如果沒有新的Intent請求達到,則自動停止Service;否則執行下一個Intent請求所對應的任務
  IntentService在處理事務時,還是採用的Handler方式,建立一個名叫ServiceHandler的內部Handler,並把它直接繫結到HandlerThread所對應的子執行緒。 ServiceHandler把處理一個intent所對應的事務都封裝到叫做onHandleIntent的虛擬函式;因此我們直接實現虛擬函式onHandleIntent,再在裡面根據Intent的不同進行不同的事務處理就可以了。
另外,IntentService預設實現了Onbind()方法,返回值為null。
  使用IntentService需要兩個步驟:
  1、寫建構函式
  2實現虛擬函式onHandleIntent,並在裡面根據Intent的不同進行不同的事務處理就可以了。
好處:處理非同步請求的時候可以減少寫程式碼的工作量,比較輕鬆地實現專案的需求
注意IntentService的建構函式一定是引數為空的建構函式,然後再在其中呼叫super("name")這種形式的建構函式。
因為Service的例項化是系統來完成的,而且系統是用引數為空的建構函式例項化Service的
關於Handler和Service的更多知識請閱讀《Looper和Handler》,《關於Handler技術》,《Service簡介》,《AIDL和Service實現兩程式通訊
Public Constructors
IntentService(String name)
Creates an IntentService.
Public Methods
IBinder onBind(Intent intent)
Unless you provide binding for your service, you don't need to implement this method, because the default implementation returns null.
void onCreate()
Called by the system when the service is first created.
void onDestroy()
Called by the system to notify a Service that it is no longer used and is being removed.
void onStart(Intent intent, int startId)
This method is deprecated. Implement onStartCommand(Intent, int, int) instead.
int onStartCommand(Intent intent, int flags, int startId)
You should not override this method for your IntentService.
void setIntentRedelivery(boolean enabled)
Sets intent redelivery preferences.

If enabled is true, onStartCommand(Intent, int, int) will return START_REDELIVER_INTENT, so if this process dies before onHandleIntent(Intent)returns, the process will be restarted and the intent redelivered. If multiple Intents have been sent, only the most recent one is guaranteed to be redelivered.

If enabled is false (the default), onStartCommand(Intent, int, int) will return START_NOT_STICKY, and if the process dies, the Intent dies along with it.

設定為true時,onStartCommand返回START_REDELIVER_INTENT,否則返回START_NOT_STICKY
關於此的更多內容請參考《Service簡介
Protected Methods
abstract void onHandleIntent(Intent intent)
This method is invoked on the worker thread with a request to process.
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().
該函式用於針對Intent的不同進行不同的事務處理就可以了.執行完所一個Intent請求物件所對應的工作之後,如果沒有新的Intent請求達到,
則自動停止Service;否則ServiceHandler會取得下一個Intent請求傳人該函式來處理其所對應的任務。


例項1
MyIntentService.java檔案
package com.lenovo.robin.test;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class MyIntentService extends IntentService {
final static String TAG="robin";
 public MyIntentService() {
  super("com.lenovo.robin.test.MyIntentService");
  Log.i(TAG,this+" is constructed");
 }
 @Override
 protected void onHandleIntent(Intent arg0) {
  Log.i(TAG,"begin onHandleIntent() in "+this);
  try {
   Thread.sleep(10*1000);
  } catch (InterruptedException e) {
     e.printStackTrace();
  }
  Log.i(TAG,"end onHandleIntent() in "+this);
 }
 public void onDestroy()
 {
  super.onDestroy();
  Log.i(TAG,this+" is destroy");
 }
}



啟動MyIntentServic的程式碼片段
Intent intent=new Intent(this,MyIntentService.class);
   startService(intent);
   startService(intent);
   startService(intent);

AndroidManifest.xml檔案程式碼片段
<service android:name=".MyIntentService" />


執行結果
09-14 22:23:34.730: I/robin(30943): com.lenovo.robin.test.MyIntentService@40541370 is constructed
09-14 22:23:34.730: I/robin(30943): begin onHandleIntent() in com.lenovo.robin.test.MyIntentService@40541370
09-14 22:23:44.730: I/robin(30943): end onHandleIntent() in com.lenovo.robin.test.MyIntentService@40541370
09-14 22:23:44.730: I/robin(30943): begin onHandleIntent() in com.lenovo.robin.test.MyIntentService@40541370
09-14 22:23:54.740: I/robin(30943): end onHandleIntent() in com.lenovo.robin.test.MyIntentService@40541370
09-14 22:23:54.740: I/robin(30943): begin onHandleIntent() in com.lenovo.robin.test.MyIntentService@40541370
09-14 22:24:04.739: I/robin(30943): end onHandleIntent() in com.lenovo.robin.test.MyIntentService@40541370
09-14 22:24:04.739: I/robin(30943): com.lenovo.robin.test.MyIntentService@40541370 is destroy
IntentService原始碼
package android.app;

import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    /**
     * You should not override this method for your IntentService. Instead,
     * override {@link #onHandleIntent}, which the system calls when the IntentService
     * receives a start request.
     * @see android.app.Service#onStartCommand
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

   protected abstract void onHandleIntent(Intent intent);
}

轉自:http://blog.csdn.net/hudashi/article/details/7986130

相關文章