intentService解析

来源:互联网 发布:提利昂 知乎 编辑:程序博客网 时间:2024/06/05 19:46

先说自己的理解:intentservice 相当于一个做完事自己了结自己的线程.

好比厉鬼,一般情况下不会被干掉,对一件事情执念很深,自己心愿完成了就自己飞升了.

注意加粗字体

再上源码

路径:alps\frameworks\base\core\java\Android\app\IntentService.java 

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) {  //自定义的IntentService子类主要就是实现onHandleIntent这个函数了。注意执行完这个之后就          //stopSelf了,传入的参数是startId。          onHandleIntent((Intent)msg.obj);          stopSelf(msg.arg1);      }  }    /**  * Creates an IntentService.  Invoked by your subclass's constructor.  *  * @param name Used to name the worker thread, important only for debugging.  */  public IntentService(String name) {      super();      mName = name;  }    /**  * Sets intent redelivery preferences.  Usually called from the constructor  * with your preferred semantics.  *  * <p>If enabled is true,  * {@link #onStartCommand(Intent, int, int)} will return  * {@link Service#START_REDELIVER_INTENT}, so if this process dies before  * {@link #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.  *  * <p>If enabled is false (the default),  * {@link #onStartCommand(Intent, int, int)} will return  * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent  * dies along with it.  */  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();  //好好看看下面这个代码,启动了一个工作线程,获取线程的Looper,然后用这个Looper初始化Handler句柄  //这样以后可以直接用mHandler.sendMessage的方式将任务直接放到工作线程了。      HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");      thread.start();        mServiceLooper = thread.getLooper();      mServiceHandler = new ServiceHandler(mServiceLooper);  }    @Override  public void onStart(Intent intent, int startId) {  //从消息队列中获取一个消息,一般都是用这种方式初始化一个消息,而不是用new message()形式      //效率更高,代码更健壮      Message msg = mServiceHandler.obtainMessage();      msg.arg1 = startId;//      msg.obj = intent;//这个就是startService的时候传入的Intent了,      mServiceHandler.sendMessage(msg);//将包含请求内容Intent的message传入到工作线程中  }    /**  * 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,和它传入的值。          onStart(intent, startId);          return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;      }        @Override      public void onDestroy() {          mServiceLooper.quit();      }        /**      * Unless you provide binding for your service, you don't need to implement this      * method, because the default implementation returns null.       * @see android.app.Service#onBind      */      @Override      public IBinder onBind(Intent intent) {          return null;      }        /**      * 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 {@link #stopSelf}.      *      * @param intent The value passed to {@link      *               android.content.Context#startService(Intent)}.      */      protected abstract void onHandleIntent(Intent intent);  }  



IntentService继承自Service,它是一个抽象类,其被创建的时候就new了一个HandlerThread和ServiceHandler,有了它,就可以利用IntentService做一些优先级较高的task,IntentService不会被系统轻易杀掉。为啥不会...我也不知道...

使用IntentService也是很简单,首先startService(intent),然后IntentService会把你的intent封装成Message然后通过ServiceHandler进行发送,接着ServiceHandler会调用onHandleIntent(Intent intent)来处理这个Message,onHandleIntent(Intent intent)中的intent就是你startService(intent)中的intent,ok,现在你需要做的是从IntentService派生一个子类并重写onHandleIntent方法,然后你只要针对不同的intent做不同的事情即可,事情完成后IntentService会自动停止。所以,IntentService是除了Thread和AsyncTask外又一执行耗时操作的方式,而且其不容易被系统干掉,建议关键操作采用IntentService。 注意:只有onHandleIntent的执行是在另外一个新线程中,其他函数(onCreate/onStart/onStartCommand等)的执行都是在main线程(主线程的名称)中


IntentService的优缺点都显而易见:

使用方便,代码简洁,不再需要我们自己像Service里面还要去创建线程;

由于是单个的worker thread,所以任务需要排队,不适合大多数的多任务情况;


自己懒的写,又怕乃们看不懂,就附个抄来的小栗子  : )

package com.test;import android.app.IntentService;import android.content.Intent;import android.util.Log;import java.lang.Thread;/** * @desc IntentService的实现类:每隔200ms将一个数字+2并通过广播发送出去 * @author skywang * */public class IntentServiceSub extends IntentService {    private static final String TAG = "skywang-->IntentServiceTest";        // 发送的广播对应的action    private static final String COUNT_ACTION = "com.test.COUNT_ACTION";        // 线程:用来实现每隔200ms发送广播    private static CountThread mCountThread = null;    // 数字的索引    private static int index = 0;        public IntentServiceSub() {        super("IntentServiceSub");        Log.d(TAG, "create IntentServiceSub");    }    @Override    public void onCreate() {        Log.d(TAG, "onCreate");        super.onCreate();    }        @Override    public void onDestroy() {        Log.d(TAG, "onDestroy");                super.onDestroy();    }        @Override    protected void onHandleIntent(Intent intent) {        Log.d(TAG, "onHandleIntent");        // 非首次运行IntentServiceSub服务时,执行下面操作        // 目的是将index设为0        if ( mCountThread != null) {            index = 0;            return;        }                // 首次运行IntentServiceSub时,创建并启动线程        mCountThread = new CountThread();        mCountThread.start();    }        private class CountThread extends Thread {        @Override         public void run() {            index = 0;            try {                while (true) {                    // 将数字+2,                    index += 2;                                                            // 将index通过广播发送出去                    Intent intent = new Intent(COUNT_ACTION);                    intent.putExtra("count", index);                    sendBroadcast(intent);//                    Log.d(TAG, "CountThread index:"+index);                                        // 若数字>=100 则退出                    if (index >= 100) {                        if ( mCountThread != null)                            mCountThread = null;                                                return ;                    }                                        // 200ms                    this.sleep(200);                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}


0 0