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

1.A Service isnota 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 isnota 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类

package com.example.testservice;import android.app.Service;import android.content.Intent;import android.os.IBinder;public class MyService extends Service{@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//该方法内可以执行耗时任务,比如下载文件等long endTime = System.currentTimeMillis() + 20 * 1000;System.out.println("onStart");while(System.currentTimeMillis() < endTime){synchronized (this) {try {wait(endTime - System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();}}}System.out.println("--耗时任务执行完毕--");return START_STICKY;}}

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

执行结果

Android菜鸟的成长笔记(20)——IntentService_第1张图片

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

(2)继承自IntentService的MyIntentService类

package com.example.testservice;import android.app.IntentService;import android.content.Intent;public class MyIntentService extends IntentService{public MyIntentService(){super("MyIntentService");}@Overrideprotected void onHandleIntent(Intent arg0) {//该方法内可以执行耗时任务,比如下载文件等long endTime = System.currentTimeMillis() + 20 * 1000;System.out.println("onStart");while(System.currentTimeMillis() < endTime){synchronized (this) {try {wait(endTime - System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();}}}System.out.println("--耗时任务执行完毕--");}}

执行结果:

Android菜鸟的成长笔记(20)——IntentService_第2张图片


更多相关文章

  1. Android 判断当前设备是手机还是平板的最有效的方法
  2. Android studio 学习1:实现点击事件的4种方法
  3. 解决方法:android 6.0(api 23) SDK,不再提供org.apache.http.*(只
  4. Android中SQLite数据库操作(2)——使用SQLiteDatabase提供的方法操
  5. 【Android笔记】Activity涉及界面全屏的方法
  6. Android Studio查看源码时出现Sources for ‘Android API 30 Pla
  7. Android中Canvas绘图方法的实现

随机推荐

  1. Android异步加载获取网络数据(图片)
  2. android hook方法收集及选择优化
  3. Android系统板子上电启动流程
  4. 编译Android内核时遇到的jdk问题
  5. Android布局——帧布局、表格布局、网格
  6. Android动态权限(兼容6.0以下和魅族手机方
  7. Unity3D之移植学习笔记:移植到Android平台
  8. android 破解软件
  9. Android中,怎么优雅的生成代码?
  10. Android(安卓)View的绘制流程(一)