除非我们特别为某个操作指定特定的线程,否则大部分线程都在前台UI界面上的执行操作。这可能存在某些隐患,因为部分在UI界面上的耗时操作可能会影响界面的响应性能。UI界面的性能问题会容易惹恼用户,甚至可能导致系统ANR错误。为了避免这样的问题,Android Framework提供了几个类,用来帮助你把那些耗时操作移动到后台线程中执行。那些类中最常用的就是IntentService.
IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。
IntentService 优点
1.不需要我们在Service中手动开线程的麻烦
2.当操作完成时,我们不用手动停止Service。
IntentService有下面几个局限性:
1.不可以直接和UI做交互。为了把他执行的结果体现在UI上,需要把结果返回给Activity。
2.工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。
3.正在执行的任务无法打断。
使用
1.创建IntentService
public class MyService extends IntentService {
/**
*重写无参构造函数
*/
public MyService(){
super("test");
}
/**
* 创建一个IntentService。调用子类的构造函数。
*
* @param name 用于命名工作线程, 只有调试情况下使用.
*/
public MyService(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
//任务队列,此处可以进行耗时操作,并且自动排队完成
......
......
}
}
2.在Manifest文件中定义IntentService
<service
android:name=".MyService"
android:exported="false"/>
在此<service>标签并没有包含任何intent filter。因为发送任务给IntentService的Activity需要使用显式Intent,所以不需要filter。这也意味着只有在同一个app或者其他使用同一个UserID的组件才能够访问到这个Service。
3.创建任务请求并发送到IntentService
例如在Activity中
Intent intent = new Intent(this, DownService.class);
// Bundle bundle = new Bundle();
// bundle.putString("videlURL" , videoUrl);
// bundle.putString("fileName" , fileName);
// intent.putExtras(bundle);
startService(intent);
当startService之后 我们的MyService 会执行onHandleIntent方法,多次点击会排队之行该方法。
如果你打印LOG 并重写 所有的 Service 生命周期方法,你会发现,多次触发startService(intent)的话,onCreate方法只执行了一次,而onStartCommand方法执行了两次,开启了两个Work Thread,这就证实了之前所说的,启动多次,但IntentService的实例只有一个,这点跟Service是一致的。