深入剖析Android系统中Service和IntentService的区别


Android中的Service是用于后台服务的,当应用程序被挂到后台的时候,问了保证应用某些组件仍然可以工作而引入了Service这个概念,那么这里面要强调的是Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。

那么我们当我们编写的耗时逻辑,不得不被service来管理的时候,就需要引入IntentService,IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期,那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去你执行你的耗时操作。

service本身存在两个问题:

(1)service不会专门启动一条单独的进程,service与它所在的应用位于同一个进程。

(2)service也不是专门新的一条线程,不应该在service中处理耗时的操作。

IntentService很好的弥补了这一点:

(1)IntentService会创建单独的worker线程来处理所有的intent请求。

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

(3)当所有的请求处理完之后,IntentService会自动停止。

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

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

所以对IntentService的使用就是:继承IntentService,重写onHandleIntent()方法即可。

tips:
(1)Intentservice也必须在manifest中声明。
(2)实现类的构造方法必须实现默认的构造方法。

这里我 需要解释以下几个方法,也许大家都已经很清楚了,不过为了抛砖引玉,我还是要提一嘴。

Service中提供了一个方法:

public int onStartCommand(Intent intent, int flags, int startId) { 
   onStart(intent, startId); 
   return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY; 
 } 

这个方法的具体含义是,当你的需要这个service启动的时候,或者调用这个servcie的时候,那么这个方法首先是要被回调的。

同时IntentService中提供了这么一个方法:

protected abstract void onHandleIntent(Intent intent); 

这是一个抽象方法,也就是说具体的实现需要被延伸到子类。

子类的声明:

public class ChargeService extends IntentService  

上面提到过IntentService是继承Service的,那么这个子类也肯定继承service,那么onHandleIntent()方法是什么时候被调用的呢?让我们具体看IntentService的内部实现:

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); 
  } 
} 
 
/** 
 * 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(); 
  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); 
} 

在这里我们可以清楚的看到其实IntentService在执行onCreate的方法的时候,其实开了一个线程HandlerThread,并获得了当前线程队列管理的looper,并且在onStart的时候,把消息置入了消息队列,

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

在消息被handler接受并且回调的时候,执行了onHandlerIntent方法,该方法的实现是子类去做的。

结论:

IntentService是通过Handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况。



相关阅读:
很酷的HTML5电子书翻页动画特效
C#生成条形码图片的简单方法
iOS应用开发中监听键盘事件的代码实例小结
详解Linux系统中的SysVinit的机制
iOS中使用schema协议调用APP和使用iframe打开APP的例子
Html5 web本地存储实例详解
设置Linux系统文件权限
如何调整mac分辨率?苹果mac分辨率设置方法
PHP实现仿Google分页效果的分页函数
iOS模仿电子书首页实现书架布局样式
JS实现仿QQ面板的手风琴效果折叠菜单代码
PHP自带方法验证邮箱是否存在
PHP正则表达式过滤html标签属性(DEMO)
jquery ajax结合thinkphp的getjson实现跨域的方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 阳春“三宝”作文700字 来自宇宙的秘密调查700字 夏晚望嵩亭有怀 小学四年级作文550字:元宵节寻宝 玩过山车作文600字 小学生广播稿大全 秋雨 麦苗 人非昔时,心却依旧 剧本作文900字 我们终究会牵手旅行作文 《游子吟》扩写 蔷薇少女馆读后感 经典现代诗歌——荷花 2013年实习工作报告 1000字 国培科学心得体会 秋叶二题 身边的案例带给我们的 放弃亦是一种美丽 玛菲尔的秘密 基层党支部书记党风廉政工作总结 用心感悟生活作文1000字 语文版《第一千个球》同步练习 浅谈挫折作文300字 镇党委书记二OO六年度党风廉政建设述职报告 文明---只差一步作文300字 让诚信回归主题班会教案 写给女人的话 这才是现实生活 我心中的“星”作文600字 荷花世界作文100字 旅游专业大学生寒假社会实践报告 好样的,玉树500字作文 申报科普文明示范社区的申报材料 初中议论文500字:作为一个中国人 你给我的爱像忧伤 诗歌我的祖国 鹌鹑斗牛 开卷有益350字 2005~2006学年度第二学期七年级下语文第一次大测试题 《自动自发》读后感1000字 我和你1000字 小学四年级作文350字:春燕 中学生寒假社会调查实践报告 和秋天有个约会 两个转身作文 2016市城乡人畜排泄物无害化处理和综合利用的设想 农业银行实习报告1000字 冬天,真好! 春天的早晨作文250字 今天阳光好灿烂 文秘类实习报告

Copyright © 2016 phpStudy |