2019-04-10:IntentService 的应用场景和使用姿势?
Moosphan opened this issue · 8 comments
IntentService
是 Service
的子类,默认为我们开启了一个工作线程,使用这个工作线程逐一处理所有启动请求,在任务执行完毕后会自动停止服务,使用简单,只要实现一个方法 onHandleIntent
,该方法会接收每个启动请求的 Intent
,能够执行后台工作和耗时操作。可以启动 IntentService
多次,而每一个耗时操作会以队列的方式在 IntentService 的 onHandlerIntent
回调方法中执行,并且,每一次只会执行一个工作线程,执行完第一个再执行第二个。并且等待所有消息都执行完后才终止服务。
IntentService
适用于 APP 在不影响当前用户的操作的前提下,在后台默默的做一些操作。
IntentService源码:
- 通过
HandlerThread
单独开启一个名为IntentService
的线程 - 创建一个名叫
ServiceHandler
的内部Handler
- 把内部Handler与HandlerThread所对应的子线程进行绑定
- 通过
onStartCommand()
传递给服务intent
,依次插入到工作队列中,并逐个发送给onHandleIntent()
- 通过
onHandleIntent()
来依次处理所有Intent
请求对象所对应的任务
使用示例:
public class MyIntentService extends IntentService {
public static final String TAG ="MyIntentService";
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
boolean isMainThread = Thread.currentThread() == Looper.getMainLooper().getThread();
Log.i(TAG,"is main thread:"+isMainThread); // 这里会打印false,说明不是主线程
// 模拟耗时操作
download();
}
/**
* 模拟执行下载
*/
private void download(){
try {
Thread.sleep(5000);
Log.i(TAG,"下载完成...");
}catch (Exception e){
e.printStackTrace();
}
}
}
IntentService是一个存在单独工作线程,onHandleIntent()在工作线程中执行,执行完毕自动销毁的Service,
使用场景是工作量较大,但具体任务明确的Service
使用姿势:首先创建一个类继承IntentService,重写onHandleIntent(Intent)方法,在清单文件中注册,然后使用context.startService等方法启动服务。
- IntentService继承Service,本质就是Service。
- IntentService创建独立的WorkerThread处理所有请求
- 其内部维护了一个WorkThread来专门处理耗时操作。主要是里面onHandleIntent()方法
- 如果start了多次,每一次都会在WorkerThread中依次执行,当全部执行完成,它就会调用stopSelf()结束自己。
- onBind()默认返回null,所以不能用bindService()来绑定IntentService
详细解析
- 一个封装了
HandlerThread
和Handler
的异步框架。 - 是一种特殊
Service
,继承自Service,是抽象类
,必须创建子类
才可以使用。 - 可用于执行后台耗时的任务,任务执行后会
自动停止
- 具有
高优先级
(服务的原因),优先级比单纯的线程
高很多,适合高优先级
的后台任务,且不容易被系统杀死。 - 启动方式和Service一样。
- 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent回调方法中执行。
- 串行执行。
IntentService的使用:
1-自定义LocalIntentService继承自IntentService
2-实现onHandleIntent(), 用于实现任务逻辑。
public class LocalIntentService extends IntentService{
public LocalIntentService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String action = intent.getStringExtra("task_action");
Log.d("IntentService", "receive task :" + action);
SystemClock.sleep(3000); //即使第一个任务休眠,后续的任务也会等待其执行完毕
if("com.example.action.TASK1".equals(action)){
Log.d("IntentService", "handle task :" + action);
}
}
}
3-开启IntentService
Intent service = new Intent(this, LocalIntentService.class);
service.putExtra("tast_action", "com.example.action.TASK1");
startService(service);
service.putExtra("tast_action", "com.example.action.TASK2");
startService(service);
service.putExtra("tast_action", "com.example.action.TASK3");
startService(service);
没有人描述一下startservice的兼容问题吗
1.IntentService 是继承自 Service 并处理异步请求的一个类。
2.在 IntentService 内有一个工作线程来处理耗时操作,当任务执行完后,IntentService 会自动停止,不需要我们去手动结束。如果启动 IntentService 多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的 onHandleIntent 回调方法中执行,依次去执行,执行完自动结束。
3.同一个IntentService只会新建一个线程,因为onCreate()方法只会被调用一次。
4.IntentService 中使用的 Handler、Looper、MessageQueue 机制把消息发送到线程中去执行的,所以多次启动 IntentService 不会重新创建新的服务和新的线程,只是把消息加入消息队列中等待执行,而如果服务停止,会清除消息队列中的消息,后续的事件得不到执行。
-
什么是 IntentService?
IntentService 是一种特殊的 Service, 它继承自 Service,是一个抽象类,子类需要重写 onHandleIntent 方法。IntentService 内部有个 HandlerThread 和 Handler,IntentService 在 onCreate 方法中创建 HandlerThread 开启工作线程,用于处理异步耗时任务,任务执行完成后会自动停止。 -
有什么优势及应用场景?
IntentService 可多次启动,工作线程内部会顺序执行。另外 IntentService 因为是服务的原因,相比普通线程具有更高的优先级,适用更高优先级的的后台任务,不容易被系统杀死。可以用作后台下载任务。 -
使用
和普通 Service 一样,注意 onBind 返回 null。
IntentService 继承于Service
IntentService的启动方式和生命周期和普通Service一样
IntentService有个onHandleIntent方法 服务启动后会执行 这个方法用于执行一些耗时操作 执行完服务就停止了