美文网首页
IntentService源码分析

IntentService源码分析

作者: BelieveFrank | 来源:发表于2019-08-18 23:37 被阅读0次

    我们知道Service是运行在主线程的,主线程中不能进行耗时操作,否则会发生ANR。Service中的发生ANR的超时时间是20s。
    有时候我们需要应用在后台默默做一些任务,例如上传文件等。如果我们采用Service,则需要我们自己手动开启新的线程。如果我们不想 自己开启线程怎么办,IntentService就出现了。

    基本使用

    public class TestService extends IntentService {
        public TestService () {
            super("TestService");
        }
        @Override
        protected void onHandleIntent(Intent intent) {
            //耗时操作
        }
    }
    

    使用IntentService需要我们继承IntentService,并重写onHandleIntent方法,在onHandleIntent中进行耗时操作。

    源码分析

    IntentService的源码比较简单,这里就直接全部贴出

    public abstract class IntentService extends Service {
        private volatile Looper mServiceLooper;
        private volatile ServiceHandler mServiceHandler;
        private String mName;
        private boolean mRedelivery;
        //子线程的Handler
        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);//将自己停掉
            }
        }
    
        public IntentService(String name) {
            super();
            mName = name;
        }
        //  设置onStartComand的返回策略
        public void setIntentRedelivery(boolean enabled) {
            mRedelivery = enabled;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");//创建一个HandlerThread
            thread.start();
            mServiceLooper = thread.getLooper();//获取子线程的Looepr
            mServiceHandler = new ServiceHandler(mServiceLooper);//创建ServiceHandler,子线程的Handler
        }
    
        @Override
        public void onStart(@Nullable Intent intent, int startId) {
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);//向子线程的Handler的发送消息,进行任务处理
        }
    
        @Override
        public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
            onStart(intent, startId);
            return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;//START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。START_NOT_STICKY:如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
        }
    
        @Override
        public void onDestroy() {
            mServiceLooper.quit();
        }
    
        @Override
        @Nullable
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @WorkerThread
        protected abstract void onHandleIntent(@Nullable Intent intent);
    }
    

    总结

    我们可以看到IntentService本质是一个Service,继承了Service。与Service的区别是内部通过维护了一个HandlerThread创建的线程,并与Handler搭配使用,达到在子线程中处理任务的目的。

    相关文章

      网友评论

          本文标题:IntentService源码分析

          本文链接:https://www.haomeiwen.com/subject/vhcjsctx.html