IntentService简介

IntentService是继承与Service的。所以IntentService也是一个Service,拥有Service的所有特性。

public abstract class IntentService extends Service

IntentService相比于Service有什么区别呢?IntentService可以执行一些耗时任务,并且任务完成后会服务会自动销毁。具体的源码分析如下:

//IntentService onCreate()方法public void onCreate() {        super.onCreate();        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");        thread.start();                mServiceLooper = thread.getLooper();        mServiceHandler = new ServiceHandler(mServiceLooper);    }

可以看出来在IntentService的onCreate()方法中创建了HandlerThread,并且开启了这个线程,然后创建了一个Handler对象,绑定HandlerThread的Looper对象,由此可知,IntentService异步任务的原理在HandlerThread+Handler。下面在看下onStart()方法:

//IntentService onStart()方法public void onStart(@Nullable Intent intent, int startId) {        Message msg = mServiceHandler.obtainMessage();        msg.arg1 = startId;        msg.obj = intent;        mServiceHandler.sendMessage(msg);    }

可以看到每次开启IntentService,会调用onStart()方法,每次的意图Intent都会包装为一个Message,然后通过Handler发送到HandlerThread内部的消息队列中,并且熟悉HandlerThread的都知道其内部是构建了一个Looper的环境的。所以可以得出,IntentSerivce对于任务是顺序处理的,因为任务都会存放在HandlerThread的消息队列中,所以IntentService其实是一个单线程+消息队列的模式。那么IntentService是如何处理任务的呢?,看如下源码:

//IntentService ServiceHandlerprivate final class ServiceHandler extends Handler {        public ServiceHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            onHandleIntent((Intent)msg.obj);            stopSelf(msg.arg1);        }    }//IntentService onHandleIntent()protected abstract void onHandleIntent(@Nullable Intent intent);

可以看出每次开启IntentService,任务会被封装成一个Message,然后有Handler发送到HandlerThread的消息队列中,最终会消息对的处理会回调onHandleIntent这个抽象方法,所以需要我们重写此方法,在此方法里执行我们的耗时任务操作。那么可以注意到onHandleIntent()方法调用后会调用stopSelf()方法,那么stopSelf()的机制是怎么样的呢?

public final void stopSelf(int startId) {        if (mActivityManager == null) {            return;        }        try {            mActivityManager.stopServiceToken(                    new ComponentName(this, mClassName), mToken, startId);        } catch (RemoteException ex) {        }    }

可以看到执行了mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);这个方法
那么并且传递了startId这个标识,每次启动IntentService都会生成这一个标识,作为一个记录。最终会调用到ActiveServices stopServiceTokenLocked(ComponentName className, IBinder token,
int startId)方法

boolean stopServiceTokenLocked(ComponentName className, IBinder token,            int startId) {        if (r != null) {            if (startId >= 0) {                ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);                if (si != null) {                    while (r.deliveredStarts.size() > 0) {                        ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);                        cur.removeUriPermissionsLocked();                        if (cur == si) {                            break;                        }                    }                }                if (r.getLastStartId() != startId) {                    return false;                }                if (r.deliveredStarts.size() > 0) {                    Slog.w(TAG, "stopServiceToken startId " + startId                            + " is last, but have " + r.deliveredStarts.size()                            + " remaining args");                }            }            synchronized (r.stats.getBatteryStats()) {                r.stats.stopRunningLocked();            }            r.startRequested = false;            if (r.tracker != null) {                r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),                        SystemClock.uptimeMillis());            }            r.callStart = false;            final long origId = Binder.clearCallingIdentity();            bringDownServiceIfNeededLocked(r, false, false);            Binder.restoreCallingIdentity(origId);            return true;        }        return false;    }

我们可以看到最关键的if (r.getLastStartId() != startId)不是最后一个startId就直接return false。否则将执行 r.stats.stopRunningLocked();来终止。自此这个问题终于真相大白了。

//HandlerThread onDestroy()方法public void onDestroy() {        mServiceLooper.quit();    }

并且IntentService停止后会调用onDestroy()生命周期方法,内部终止了HandlerThread内部的loop循环,进而使得HandlerThread也随之结束。

IntentService的使用场景

根据以上的分析,可以得知IntentService可以用来处理耗时的后台任务,相比我们新开一个线程,它在任务完成时会主动关闭,且内部处理任务是顺序执行的,多次开启IntentService,任务会在队列中排队,依次被执行。且IntentService是服务的特性,可以相应的提高进程优先级。

更多相关文章

  1. Android(安卓)Studio maven-metadata.xml 卡着不动原因和解决方
  2. android 蓝牙源码分析
  3. Android: NullPointerException when using RelativeLayout with
  4. 一个使用openGL渲染的炫丽Android动画库
  5. Android(安卓)Webview js或css 替换 注入
  6. Android架构组件
  7. Android辅助功能AccessibilityService自动全选择文字粘贴模拟输
  8. Android开发艺术探索 - 第10章 Android的消息机制
  9. Android(安卓)OpenGL ES 开发中的Buffer使用

随机推荐

  1. PHP中的输出缓冲控制详解
  2. 详解PHP使用OSS上传文件
  3. 如何使用SublimeText3配置 PHP IDE环境
  4. 如何在thinkphp中使用windows计划任务定
  5. 布局实战小结
  6. PHP输出缓冲与header发送问题详解
  7. 如何画动漫人物侧脸?人物侧脸画法教程!
  8. 模态框练习
  9. grid网格布局最新课程部分
  10. php中文网右侧区域的实例演示