Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-04-10:IntentService 的应用场景和使用姿势?

Moosphan opened this issue · comments

2019-04-10:IntentService 的应用场景和使用姿势?

IntentServiceService 的子类,默认为我们开启了一个工作线程,使用这个工作线程逐一处理所有启动请求,在任务执行完毕后会自动停止服务,使用简单,只要实现一个方法 onHandleIntent,该方法会接收每个启动请求的 Intent,能够执行后台工作和耗时操作。可以启动 IntentService 多次,而每一个耗时操作会以队列的方式在 IntentService 的 onHandlerIntent 回调方法中执行,并且,每一次只会执行一个工作线程,执行完第一个再执行第二个。并且等待所有消息都执行完后才终止服务。

IntentService 适用于 APP 在不影响当前用户的操作的前提下,在后台默默的做一些操作。

IntentService源码:

  1. 通过 HandlerThread 单独开启一个名为 IntentService 的线程
  2. 创建一个名叫 ServiceHandler 的内部 Handler
  3. 把内部Handler与HandlerThread所对应的子线程进行绑定
  4. 通过 onStartCommand() 传递给服务 intent,依次插入到工作队列中,并逐个发送给 onHandleIntent()
  5. 通过 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
    详细解析
  1. 一个封装了HandlerThreadHandler的异步框架。
  2. 是一种特殊Service,继承自Service,是抽象类,必须创建子类才可以使用。
  3. 可用于执行后台耗时的任务,任务执行后会自动停止
  4. 具有高优先级(服务的原因),优先级比单纯的线程高很多,适合高优先级的后台任务,且不容易被系统杀死。
  5. 启动方式和Service一样。
  6. 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent回调方法中执行。
  7. 串行执行。

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方法 服务启动后会执行 这个方法用于执行一些耗时操作 执行完服务就停止了