个人关于使用IntentService的思考
来源:互联网 发布:淘宝贷款多久放款 编辑:程序博客网 时间:2024/06/09 22:18
最近要做个多app module 位于一个Project 下的 启动优化,创建公用的IntentService到各自的Application中差异化实现细节。不想使用静态的Application实例作为回调对象传入,因此有了以下伪代码。
package com.personalcenter.service;import android.app.IntentService;import android.content.Context;import android.content.Intent;import android.os.Binder;import android.support.annotation.Nullable;import android.util.Log;import com.personalcenter.util.ProguardUtil;import java.util.concurrent.CountDownLatch;/** * app 启动优化 后台执行任务回调由外界决定执行任务内容 * Created by dhs on 17/12/23 */public class InitIntentService extends IntentService { private Listener mListener; public static final String APP_INIT_ACTION = "app_init_action"; private final CountDownLatch mLatch; /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public InitIntentService() { super(InitIntentService.class.getCanonicalName()); Log.e("InitIntentService", "InitIntentService(InitIntentService.java:31)" + this); mLatch = new CountDownLatch(1); } public static InitIntentService startBackService(Context context) { Intent intent = new Intent(context, InitIntentService.class); intent.setAction(APP_INIT_ACTION); // 可通过该action来分类处理任务 context.startService(intent); return new InitIntentService(); } public void setHandleBackListener(Listener listener) { Log.e("InitIntentService", "setHandleBackListener(InitIntentService.java:41)" + Thread.currentThread() + "service-->>" + this); mLatch.countDown(); mListener = listener; } @Override protected void onHandleIntent(@Nullable Intent intent) { //do background init try { Log.e("InitIntentService", "onHandleIntent(InitIntentService.java:51)" + Thread.currentThread() +"service-->>"+ this); mLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } ProguardUtil.checkNotNull(mListener, "Listener should not be null at first init..."); mListener.doBackgroundInit(); } public interface Listener { void doBackgroundInit(); } @Override public void onCreate() { Log.e("InitIntentService", "onCreate(InitIntentService.java:68)-->>" + this); super.onCreate(); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { Log.e("InitIntentService", "onStartCommand(InitIntentService.java:73)-->>" + this); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.e("InitIntentService", "onDestroy(InitIntentService.java:80)-->>" + this); super.onDestroy(); }}
上述代码为本人新建IntentService 的伪尝试代码,尝试外界静态方法调用创建service,并通过service对象传递接口回调对象
问题:
1. Service 的创建是交给系统的,不同于Fragment这种类view形式,所以new 构造创建Service会在start 基础上额外创建一个Service对象。
且通过new 构造创建的Service不会走Service的生命周期方法。
2. 通过以下方式完成创建和接口回调对象的传递:
InitIntentService.startBackService(this).setHandleBackListener(this);
IntentService的原理是通过HandlerThread来实现子线程在后台处理任务,而HandlerThread则是在Thread的基础上添加Looper构建子线程处理任务的环境。
通过上述方法将app 实例传到的对象非最终走系统回调的IntentService对象。
3. 系统在创建出IntentService实例后[系统调用对应构造函数创建],调用Service生命周期函数 onCreate和onStartCommand,
在IntentService源码中:
...HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);...
在onStartCommand 中调用onStart方法:
...mServiceHandler.sendMessage(msg);...
在ServiceHandler中处理:
private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } }
最终Handler所post的内容会在Handler所绑定的looper线程中的MessageQueue中dispatch,即 onHandleIntent在IntentService里的
handlerThread所创建的Thread中执行。
4.基于上述分析,两个IntentService的创建后,通过new 构建的Service对象持有了app实例,而系统创建的Service并没有调用传递回调对象的方法 setHandleBackListener,而且只有系统创建的Service才会走生命周期方法,那么在onHandleIntent
回调中,传入的回调对象必定为null,调用多线程锁对象
mLatch.await(); 则会让子线程一直等待,因为系统创建的Service没有调用传入回调对象的方法,也就不会 执行 mLatch.countDown(); onHandleIntent 后续的代码也就不会执行!
另:CountDownLatch 是用于多线程间控制执行流程的位于java 并发包下的同步辅助类,允许一个或多个类挂起(await),在调用countdown后继续执行。
- 个人关于使用IntentService的思考
- 关于个人综合能力的个人思考
- 关于IntentService与Service的使用选择
- 关于个人价值、职业规划、婚姻的思考
- 谈谈关于个人提升的一些思考
- 谈谈关于个人提升的一些思考
- 关于建立个人小网站的思考
- 关于goto语句的一些个人思考~
- 关于软件测试的个人思考
- IntentService的使用
- Android:IntentService的使用
- Android IntentService 的使用
- 【安卓篇】IntentService的使用
- IntentService的使用
- IntentService 的使用
- Android IntentService的使用
- IntentService的使用介绍
- IntentService的使用
- 《spring cloud微服务实战》读书笔记——Spring Cloud Hystrix(二)工作流程
- 用netsh命令实现快速切换网络状态(IP,DNS等)
- 对Python的见解
- 图形数据库Neo4J简介
- log4j的使用
- 个人关于使用IntentService的思考
- Java 中怎么打印数组?
- MySQL数据库性能优化-利用sql执行计划预先查看执行性能(五)
- js如何获取当前用户访问的ip地址以及城市地区?
- 兄弟连学Python(5) -- 块排方法进行排序
- 机械臂的运动规划和运动学都是成熟的
- DB2开发与性能优化
- mysql的安装
- 《spring cloud微服务实战》读书笔记——Spring Cloud Hystrix(三)断路器的原理