Android菜鸟的成长笔记(20)——IntentService

前面介绍的Service在官方文档介绍中说Service存在着如下两个问题:

1.A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.

2.A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).

1、Service不会专门启动一条单独的进程,Service与它所在的应用在同一个进程中。

2、Service不是专门一条新的线程,因此不能再Service中直接处理耗时任务。

如果开发者在Service中处理耗时任务,建议在Service中另外启动一条新的线程来处理耗时的任务,可能有的朋友就会问:“既然在Service中处理耗时任务需要启动新线程,为什么我们不直接在Activity中开启一个新线程,而要使用Service呢?”

其实这种在Activity中直接启动一个线程来实现对有些业务逻辑是非常不可靠的,比如:用户使用BroadcastReceiver来启动一个新线程,BroadcastReceiver的生命周期非常短,这样就可能存在这样的问题,在子线程还没有结束的情况下,BroadcastReceiver已经结束了,或者用户在Activity中启动一个新线程后直接退出,此时它们所在的进程就变成了空进程(没有任何活动组件的进程),系统需要内存时可能会优先终止该进程。如果宿主进程被终止,那么该进程内的所有子线程也会被终止,这样就有可能导致一些严重错误。

IntentService是Service的子类,所以它比Service增加了额外的功能,它正好弥补了Service的上述两点不足:IntentService将会使用队列来管理请求Intent,每当客户端代码通过Intent请求启动IntentService时,IntentService会将该Intent加入队列中,然后开启一条新的worker线程来处理该Intent.对于异步的startService()请求,IntentService会按次序依次处理队列中的Intent,该线程保证同一时刻只处理一个Intent.由于IntentService使用新的worker线程处理Intent请求,因此IntentService不会阻塞主线程,所以IntentService就可以处理耗时任务。

IntentService有如下特征:

1、会创建单独的worker线程来处理所有的Intent请求。

2、会创建单独的worker线程来处理onHandleIntent()方法实现的代码。

3、所有请求处理完成后,IntentService会自动停止,因此开发者无须调用stopSelf()方法

4、为Service的onBind()方法提供了默认的实现,默认实现的onBind()方法返回null

5、为Service的onStartCommand()方法提供了默认实现,该实现会将请求的Intent添加到队列中。

从上面的特点中可以看出来,扩展的IntentService实现Service无须重写onBind()方法和onStartCommand()方法,只要重写onHandleIntent()方法即可。

下面通过一个具体例子来说明IntentService和Service的区别:

(1)继承自Service的MyService类

  1. package com.example.testservice;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.IBinder;  
  6.   
  7. public class MyService extends Service{  
  8.   
  9.     @Override  
  10.     public IBinder onBind(Intent intent) {  
  11.           
  12.         return null;  
  13.     }  
  14.   
  15.     @Override  
  16.     public int onStartCommand(Intent intent, int flags, int startId) {  
  17.         //该方法内可以执行耗时任务,比如下载文件等  
  18.         long endTime = System.currentTimeMillis() + 20 * 1000;  
  19.         System.out.println("onStart");  
  20.         while(System.currentTimeMillis() < endTime){  
  21.             synchronized (this) {  
  22.                 try {  
  23.                     wait(endTime - System.currentTimeMillis());  
  24.                 } catch (InterruptedException e) {  
  25.                     e.printStackTrace();  
  26.                 }  
  27.             }  
  28.         }  
  29.         System.out.println("--耗时任务执行完毕--");  
  30.         return START_STICKY;  
  31.     }  
  32. }  

读者可能会注意到onStartCommand方法最后的返回值我设置成了START_STICKY,有关返回值的详细设置及含义将在下一篇文章中介绍。

执行结果


可以看到在Service中执行耗时任务程序的主UI会被阻塞,出现ANR异常。

(2)继承自IntentService的MyIntentService类

  1. package com.example.testservice;  
  2.   
  3. import android.app.IntentService;  
  4. import android.content.Intent;  
  5.   
  6. public class MyIntentService extends IntentService{  
  7.   
  8.     public MyIntentService(){  
  9.         super("MyIntentService");  
  10.     }  
  11.   
  12.     @Override  
  13.     protected void onHandleIntent(Intent arg0) {  
  14.         //该方法内可以执行耗时任务,比如下载文件等  
  15.         long endTime = System.currentTimeMillis() + 20 * 1000;  
  16.         System.out.println("onStart");  
  17.         while(System.currentTimeMillis() < endTime){  
  18.             synchronized (this) {  
  19.                 try {  
  20.                     wait(endTime - System.currentTimeMillis());  
  21.                 } catch (InterruptedException e) {  
  22.                     e.printStackTrace();  
  23.                 }  
  24.             }  
  25.         }  
  26.         System.out.println("--耗时任务执行完毕--");  
  27.     }  
  28. }  

执行结果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值