zoukankan      html  css  js  c++  java
  • 什么是 IntentService

    service 默认也运行在 UI 线程,所以里面不能直接做耗时操作,要做耗时操作还得开启子线程来做。

    IntentService 就是一个 Service, 只不过里面给你默认开启了一个子线程来处理所有的 intent 请求。

    而多次调用 startService 时所有请求都会放到这个子线程中一个接一个的按顺序执行,等所有的请求都处理完毕后 service 会自动销毁。

    一句话描述就是用一个子线程来依次处理各个请求,请求按顺序一个接一个执行。按顺序执行是通过 Looper 队列实现的。

     看看源码就清晰了

    /**
     * 这段注释应该多读几遍
     * IntentService is a base class for Service that handle asynchronous
     * requests (expressed as Intent) on demand.  Clients send requests
     * through startService(Intent)} calls; the
     * service is started as needed, handles each Intent in turn using a worker
     * thread, and stops itself when it runs out of work.
     *
     * All requests are handled on a single worker thread -- they may take as
     * long as necessary (and will not block the application's main loop), but
     * only one request will be processed at a time.
     */
    public abstract class IntentService extends Service {
        private volatile Looper mServiceLooper;
        private volatile ServiceHandler mServiceHandler;
        private String mName;
        private boolean mRedelivery;
    
        private final class ServiceHandler extends Handler {
            public ServiceHandler(Looper looper) {
                super(looper);
            }
    
            @Override
            public void handleMessage(Message msg) {
                // handleMessage 还是在 onCreate 中启动的子线程中执行,因为 Looper 在哪个线程 handler 就在哪个线程执行
                // 消息队列保证了所有请求按顺序执行
                onHandleIntent((Intent)msg.obj);
    
                // 这里貌似停止了服务, 其实不是只有当 startId 等于最后一次启动服务时的 startId 时服务才会销毁
                stopSelf(msg.arg1);
            }
        }
    
        public IntentService(String name) {
            super();
            mName = name;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            // onCreate 时启动一个带有 Looper 的子线程
            HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
            thread.start();
    
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);
        }
    
        @Override
        public void onStart(Intent intent, int startId) {
            // 每次 onStart 时都发送一个消息到消息队列中等待执行
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            onStart(intent, startId);
            return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
        }
    
        @Override
        public void onDestroy() {
            mServiceLooper.quit();
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        /**
         * 这段注释也应该多读几遍
         * This method is invoked on the worker thread with a request to process.
         * Only one Intent is processed at a time, but the processing happens on a
         * worker thread that runs independently from other application logic.
         * So, if this code takes a long time, it will hold up other requests to
         * the same IntentService, but it will not hold up anything else.
         * When all requests have been handled, the IntentService stops itself,
         * so you should not call stopSelf.
         */
        @WorkerThread
        protected abstract void onHandleIntent(Intent intent);
    }

    看似简单其实里面东西挺多,发现网上好多人理解有误区,有人认为是每 start 一次都开启一个 worker 线程, 其实不是如果 service 还没有销毁多次调用

    都只有一个线程来按顺序来处理请求。

  • 相关阅读:
    Delphi 正则表达式之TPerlRegEx 类的属性与方法(3): Start、Stop
    Delphi 正则表达式之TPerlRegEx 类的属性与方法(2): 关于子表达式
    Delphi 正则表达式之TPerlRegEx 类的属性与方法(1): 查找
    Delphi 正则表达式语法(10): 选项
    Delphi 正则表达式语法(9): 临界匹配
    Delphi 正则表达式语法(8): 引用子表达式
    Delphi 正则表达式语法(7): 匹配转义字符
    看阿里P7讲MyBatis:从MyBatis的理解以及配置和实现全帮你搞懂
    公司新来的小姐姐不懂java中的static关键字,这样给她描述不香吗?
    2020阿里,字节跳动,JAVA岗(一线企业校招、社招)面试题合集
  • 原文地址:https://www.cnblogs.com/lesliefang/p/5363513.html
Copyright © 2011-2022 走看看