4.IntentService源码分析php
IntentService的介绍android
IntentService的做用git
目前,因为正式项目中application初始化工做太多,因此决定分担部分逻辑到IntentService中处理 好比:如今application初始化内容有:数据库初始化,阿里云推送初始化,腾讯bugly初始化,im初始化,神策初始化,内存泄漏工具初始化,头条适配方案初始化,阿里云热修复……等等。将部分逻辑放到IntentService中处理,能够缩短不少时间。
步骤1:定义InitializeService类,而且须要继承IntentService的子类github
//第一步 InitializeService.start(this); //第二步 <service android:name=".InitializeService"/> //第三步 public class InitializeService extends IntentService { private static final String ACTION_INIT = "initApplication"; public static void start(Context context) { Intent intent = new Intent(context, InitializeService.class); intent.setAction(ACTION_INIT); context.startService(intent); } public InitializeService(){ //注意这里须要写类的名称 super("InitializeService"); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_INIT.equals(action)) { initApplication(); } } } private void initApplication() { //处理耗时操做和避免在application作过多初始化工做,好比初始化数据库等等 } }
IntentService实际上内部实例化了一个HandlerThread,而且封装了一个Handler,因此他的工做流程经过上面的源码,分析以下:数据库
/** * <pre> * @author yangchong * blog : https://github.com/yangchong211 * time : 2017/01/22 * desc : 初始化工做,子线程,处理耗时操做和避免在application作过多初始化工做,好比初始化数据库等等 * revise: * </pre> */ public abstract class IntentService extends Service { //子线程中的Looper private volatile Looper mServiceLooper; //内部持有的一个mServiceHandler对象 private volatile ServiceHandler mServiceHandler; //内部建立的线程名字 private String mName; //服务被异常终止后从新建立调用onStartCommand是否回传Intent private boolean mRedelivery; /** * 内部建立了一个ServiceHandler,而后将传递过来的Intent封装成一个Message, * 而后再将Message封装成一个Intent,回调onHandleIntent,其实转换的目的就是 * 将主线程的Intent切换到子线程中去执行了而已。 */ private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { //处理发送过来的消息,在子线程 onHandleIntent((Intent)msg.obj); //处理完消息以后中止Service stopSelf(msg.arg1); } } /** * 工做线程的名字 * @param name name */ public IntentService(String name) { super(); mName = name; } public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { super.onCreate(); //建立HandlerThread HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); //开启线程建立子线程Looper thread.start(); //获取子线程Looper mServiceLooper = thread.getLooper(); //建立子线程Handler mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(@Nullable Intent intent, int startId) { //建立一个Message Message msg = mServiceHandler.obtainMessage(); //消息标志,做为当前Service的标志 msg.arg1 = startId; //携带Intent msg.obj = intent; //发送消息,此时将线程切换到子线程 mServiceHandler.sendMessage(msg); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { //调用onStart方法 onStart(intent, startId); //根据mRedelivery的值来肯定返回重传Intent的黏性广播仍是非黏性广播 return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { //退出Looper mServiceLooper.quit(); } @Override @Nullable public IBinder onBind(Intent intent) { return null; } /*子类必须实现的抽象方法*/ @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent); }
// IntentService源码中的 onCreate() 方法 @Override public void onCreate() { super.onCreate(); // HandlerThread继承自Thread,内部封装了 Looper //经过实例化andlerThread新建线程并启动 //因此使用IntentService时不须要额外新建线程 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); //得到工做线程的 Looper,并维护本身的工做队列 mServiceLooper = thread.getLooper(); //将上述得到Looper与新建的mServiceHandler进行绑定 //新建的Handler是属于工做线程的。 mServiceHandler = new ServiceHandler(mServiceLooper); } private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } //IntentService的handleMessage方法把接收的消息交给onHandleIntent()处理 //onHandleIntent()是一个抽象方法,使用时须要重写的方法 @Override public void handleMessage(Message msg) { // onHandleIntent 方法在工做线程中执行,执行完调用 stopSelf() 结束服务。 onHandleIntent((Intent)msg.obj); //onHandleIntent 处理完成后 IntentService会调用 stopSelf() 自动中止。 stopSelf(msg.arg1); } } //onHandleIntent()是一个抽象方法,使用时须要重写的方法 @WorkerThread protected abstract void onHandleIntent(Intent intent);
public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; //把 intent 参数包装到 message 的 obj 中,而后发送消息,即添加到消息队列里 //这里的Intent 就是启动服务时startService(Intent) 里的 Intent。 msg.obj = intent; mServiceHandler.sendMessage(msg); } //清除消息队列中的消息 @Override public void onDestroy() { mServiceLooper.quit(); }
分析:segmentfault
@Override public IBinder onBind(Intent intent) { return null; }
并不会调用onstart()或者onstartcommand()方法,因此不会将消息发送到消息队列,那么onHandleIntent()将不会回调,即没法实现多线程的操做。多线程