IntentSevice为在单一后台线程中执行任务提供了一种直接的实现方式。它可以处理一个耗时的并确保不会影响到UI的响应性。另外IntentService的执行还不受UI生命周期的影响,以确保AsyncTask能够顺利运行。
但是IntentService有以下局限性:
-
- 不可以直接和UI做交互,为了他能把执行的结果体现在UI上,需要把结果返回给Activity
- 工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你在发送一个新的任务请求,这个新的任务会一直等待前面的任务执行完毕才开始执行
- 正在执行的任务无法打断
- 创建IntentService
定义一个类,继承自IntentService,并重写onHandleIntent()方法
public class MyIntentService extends IntentService(){
protected void onHandleIntent(Intent intent){
......
}
}
注意:一个普通Service组件的其他回调,例如onStartCommand()会被IntentService自动调用。在IntentService中,避免重写那些回调。
- 在Manifest文件中定义IntentService
<sevice
android:name=".MyIntentService"
android:exported="false">
注:在<service>标签中并没有包含任何intent filter。因为发任务给IntentService的Activity需要使用显式Intent,所以不需要filter.这也意味着只有在同一个app才能访问到这个Service.
- 创建任务请求并发送到IntentService
首先需要创建一个显式Intent,并将请求数据添加到intent中,然后调用startService()方法把任务请求发送到IntentService
Intent i = new Intent(getActivity(),MyIntentService.class);
i.setData(Uri.parse(dataUrl));
- 执行startService
getActivity().startService(i);
注意:可以在Activity或者Fragment的任何位置发生任务请求。例如,如果你先获取用于输入,可以从响应按钮单击或是类似于手势的回调方法里发送任务请求。
一旦执行了startService(),IntentService在自己本身的onHandleIntent()方法里面开始执行这个任务,任务结束后,会自动停止这个Service
- 报告任务执行状态
回传IntentService中执行任务的结果给发送方。例如:回传任务的执行状态给Activity并进行更新UI。推荐的方式是使用LocalBroadcastManager,这个组件可以限制broadcast intent只在自己的app中进行传递
Service和IntentService:
其实它们没什么区别,只是IntentService在onCreate方法中开启了新的HandlerThread去执行。
Service运行的进程和线程:
当它运行的时候如果是LocalService,那么对应的Service是运行在主线程的main线程上,如onCreate()、onStartCommand()等方法都是在系统调用的时候运行在主线程上的main线程上的。如果是RemoteService,那么对应的Service则是运行在独立的main线程上的。
android-Service和Thread的区别:
- Service不是单一的进程。Service没有自己的进程,应用程序可以不同,Service运行在相同的进程中。
- Service不是线程,可以在线程中工作
一、在应用中,如果长时间的在后台运行,而且不需要交互的情况下,使用service。
同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需要长时间运行的情况下使用线程。
二、如果任务占用CPU时间多,资源大的情况下,要使用线程
Service是系统组件,它由系统进程托管(servicemanager),它们之间的通信类似于client和server,是一种轻量级的IPC通信,这种通信的载体是Binder,它是在Linux层交换信息的一种IPC。而thread是由本应用程序托管。
1)Thread:是程序执行的最小单元,用来资源调度。
2)Service:Service是android的一种组件。
当它运行的时候如果是LocalService,那么对应的Service是运行在主线程的main线程上,如onCreate()、onStartCommand()等方法都是在系统调用的时候运行在主线程上的main线程上的。如果是RemoteService,那么对应的Service则是运行在独立的进程的main线程上的。
我们为什么要用Service?不用Thread?
我们先来说说Thread,Thread的运行时独立于activity的。也就是说activity被finish之后,如果你没有主动停止Thread或是Thread的run()方法没有执行完毕的话,Thread也会一直执行。因此这里会出现一个问题:当Activity被finish以后,你就不再持有该Thread的引用。另一方面,你没有办法在不同的Activity中对同一Thread进行控制。
例如:如果你的Thread需要不停的地隔一段时间就要连接服务器,该Thread需要在Activity没有start的时候也运行。这时候当你start一个Activity就没有办法在该Activity里面控制之前创建的Thread。因此你需要创建并启动一个Service,在Service里面创建、运行控制该Thread.因为任何Activity都可以控制同一个service,而系统也会创建一个service实例。
因此,可以把service想象成一种消息服务,你可以在任何有Context的地方调用Context.startService、
Context.stopService、
Context.bindService、
Context.unbindService来控制它。你也可以在service里注册BroadcastReceiver,在其他地方通过发送broadcast来控制它,这些Thread没办法做到。