Service与 IntentService 的区别与使用场景(源代码剖析)

来源:互联网 发布:数据分析的模型 编辑:程序博客网 时间:2024/06/11 17:35

1)IntentService是继承自Service的

(2)1.Service不是一个单独的进程 ,它和应用程序在同一个进程中。

        2.Service不是一个线程,所以我们应该避免在Service里面进行耗时的操作

(3)IntentService相对于Service来说,有几个非常有用的优点

    IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。


因为最大部分的service不需要同时处理多个请求(处理多个请求是一个比较危险的多线程的场景),这样在在这种情况下呢,最好使用IntentService类如果你实现你的服务。

  使用intentService与service有什么不同呢

 (1)直接 创建一个默认的工作线程,该线程执行所有的intent传递给onStartCommand()区别于应用程序的主线程。

 (2)直接创建一个工作队列,将一个意图传递给你onHandleIntent()的实现,所以我们就永远不必担心多线程。

 (3)当请求完成后自己会调用stopSelf(),所以你就不用调用该方法了。

 (4)提供的默认实现onBind()返回null,所以也不需要重写这个方法。so easy啊

 (5)提供了一个默认实现onStartCommand(),将意图工作队列,然后发送到你onHandleIntent()实现。真是太方便了

   我们需要做的就是实现onHandlerIntent()方法,还有一点就是经常被遗忘的,构造函数是必需的,而且必须调用超IntentService(字符串) ,因为工作线程的构造函数必须使用一个名称。如何实现呢,我们借助于谷歌官方文档来看一下吧。

[java] view plaincopy
  1. public class HelloIntentService extends IntentService {  
  2.   
  3.   /** 
  4.    * A constructor is required, and must call the super IntentService(String) 
  5.    * constructor with a name for the worker thread. 
  6.    */  
  7.   public HelloIntentService() {  
  8.       super("HelloIntentService");  
  9.   }  
  10.   
  11.   /** 
  12.    * The IntentService calls this method from the default worker thread with 
  13.    * the intent that started the service. When this method returns, IntentService 
  14.    * stops the service, as appropriate. 
  15.    */  
  16.   @Override  
  17.   protected void onHandleIntent(Intent intent) {  
  18.       // Normally we would do some work here, like download a file.  
  19.       // For our sample, we just sleep for 5 seconds.  
  20.       long endTime = System.currentTimeMillis() + 5*1000;  
  21.       while (System.currentTimeMillis() < endTime) {  
  22.           synchronized (this) {  
  23.               try {  
  24.                   wait(endTime - System.currentTimeMillis());  
  25.               } catch (Exception e) {  
  26.               }  
  27.           }  
  28.       }  
  29.   }  
  30. }  

那么它为什么不用stopself()方法呢,我们看一下自身的源代码把

[java] view plaincopy
  1. public abstract class IntentService extends Service {  
  2.     private volatile Looper mServiceLooper;  
  3.     private volatile ServiceHandler mServiceHandler;  
  4.     private String mName;  
  5.     private boolean mRedelivery;  
  6.   
  7.     private final class ServiceHandler extends Handler {  
  8.         public ServiceHandler(Looper looper) {  
  9.             super(looper);  
  10.         }  
  11.   
  12.         @Override  
  13.         public void handleMessage(Message msg) {  
  14.             onHandleIntent((Intent)msg.obj);  
  15.             stopSelf(msg.arg1);  
  16.         }  
  17.     }  
  18.   
  19.     /** 
  20.      * Creates an IntentService.  Invoked by your subclass's constructor. 
  21.      * 
  22.      * @param name Used to name the worker thread, important only for debugging. 
  23.      */  
  24.     public IntentService(String name) {  
  25.         super();  
  26.         mName = name;  
  27.     }  
  28.   
  29.     /** 
  30.      * Sets intent redelivery preferences.  Usually called from the constructor 
  31.      * with your preferred semantics. 
  32.      * 
  33.      * <p>If enabled is true, 
  34.      * {@link #onStartCommand(Intent, int, int)} will return 
  35.      * {@link Service#START_REDELIVER_INTENT}, so if this process dies before 
  36.      * {@link #onHandleIntent(Intent)} returns, the process will be restarted 
  37.      * and the intent redelivered.  If multiple Intents have been sent, only 
  38.      * the most recent one is guaranteed to be redelivered. 
  39.      * 
  40.      * <p>If enabled is false (the default), 
  41.      * {@link #onStartCommand(Intent, int, int)} will return 
  42.      * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent 
  43.      * dies along with it. 
  44.      */  
  45.     public void setIntentRedelivery(boolean enabled) {  
  46.         mRedelivery = enabled;  
  47.     }  
  48.   
  49.     @Override  
  50.     public void onCreate() {  
  51.         // TODO: It would be nice to have an option to hold a partial wakelock  
  52.         // during processing, and to have a static startService(Context, Intent)  
  53.         // method that would launch the service & hand off a wakelock.  
  54.   
  55.         super.onCreate();  
  56.         HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");  
  57.         thread.start();  
  58.   
  59.         mServiceLooper = thread.getLooper();  
  60.         mServiceHandler = new ServiceHandler(mServiceLooper);  
  61.     }  
  62.   
  63.     @Override  
  64.     public void onStart(Intent intent, int startId) {  
  65.         Message msg = mServiceHandler.obtainMessage();  
  66.         msg.arg1 = startId;  
  67.         msg.obj = intent;  
  68.         mServiceHandler.sendMessage(msg);  
  69.     }  
  70.   
  71.     /** 
  72.      * You should not override this method for your IntentService. Instead, 
  73.      * override {@link #onHandleIntent}, which the system calls when the IntentService 
  74.      * receives a start request. 
  75.      * @see android.app.Service#onStartCommand 
  76.      */  
  77.     @Override  
  78.     public int onStartCommand(Intent intent, int flags, int startId) {  
  79.         onStart(intent, startId);  
  80.         return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;  
  81.     }  
  82.   
  83.     @Override  
  84.     public void onDestroy() {  
  85.         mServiceLooper.quit();  
  86.     }  
  87.   
  88.     /** 
  89.      * Unless you provide binding for your service, you don't need to implement this 
  90.      * method, because the default implementation returns null.  
  91.      * @see android.app.Service#onBind 
  92.      */  
  93.     @Override  
  94.     public IBinder onBind(Intent intent) {  
  95.         return null;  
  96.     }  
  97.   
  98.     /** 
  99.      * This method is invoked on the worker thread with a request to process. 
  100.      * Only one Intent is processed at a time, but the processing happens on a 
  101.      * worker thread that runs independently from other application logic. 
  102.      * So, if this code takes a long time, it will hold up other requests to 
  103.      * the same IntentService, but it will not hold up anything else. 
  104.      * When all requests have been handled, the IntentService stops itself, 
  105.      * so you should not call {@link #stopSelf}. 
  106.      * 
  107.      * @param intent The value passed to {@link 
  108.      *               android.content.Context#startService(Intent)}. 
  109.      */  
  110.     protected abstract void onHandleIntent(Intent intent);  
  111. }  
  我们可以看到源代码里头的第15行handlerMessage方法里当处理完请求后就会调用stopself()方法了,外界就不用调用了,此外还有一点我们可以看到代码最后一行第110行,onhandleIntent()是一个抽象类,而其他类都是抽象类,所以我们就可以理解为什么只需要重写onhandleIntent()方法了吧。
0 0
原创粉丝点击