IntentService和HandlerThread的使用以及源码阅读

简介

使用

源码分析

简介

IntentService是一种特殊的service,一般用来执行一些耗时任务,作用类似于Thread,但是相对于普通的thread,service的系统优先级更高,不容易被杀死。所以IntentService准确来说,适合用来执行一些,比较重要的后台任务。

而HandlerThread则是继承thread的,一种特殊的thread,一般用来搭配IntentService使用而不单独使用。


使用

MyIntentService.java


public class MyIntentService extends IntentService {


    /**

     * 是否正在运行

     */

    private boolean isRunning;


    /**

     *进度

     */

    private int count;


    public MyIntentService() {

        super("test");

    }


    /**

     * Creates an IntentService.  Invoked by your subclass's constructor.

     *

     * @param name Used to name the worker thread, important only for debugging.

     */

    public MyIntentService(String name) {

        super(name);

    }



    @Override

    protected void onHandleIntent(Intent intent) {

        Logout.e("onHandleIntent"+intent.getStringExtra("name"));

        try {

            Thread.sleep(1000);

            isRunning = true;

            count = 0;

            while (isRunning) {

                count++;

                if (count >= 100) {

                    isRunning = false;

                }

                Thread.sleep(50);

                Logout.e("线程运行中..."+ count);

            }

郑州妇科医院:http://jbk.39.net/yiyuanzaixian/sysdfkyy/

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        Logout.e("结束了任务");

    }




    @Override

    public void onDestroy() {

        super.onDestroy();

        Logout.e("线程结束运行..." + count);

    }


    public static class Logout{

        private static final String TAG = "Logout";

        public static void e(String conent){

            Log.d(TAG, "e: "+conent);

        }

    }


}


public classTestActivity extends AppCompatActivity {



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_async_task);


        startService(new Intent(this, MyIntentService.class));

        new Handler().post(new Runnable() {

            @Override

            public void run() {

            //延迟一段时间,发送第二次消息

                Intent intent = new Intent(AsyncTaskActivity.this, MyIntentService.class);

                intent.putExtra("name", "helloWorld");

                startService(intent);

            }

        });

    }


    @Override

    protected void onDestroy() {

        super.onDestroy();

//        handlerThread.quit();

        //      unbindService(serviceConnection);

    }

 }


上面就是简单的使用IntentService的教程。 IntentService是一个抽象类,所以需要自己集成实现,这里有两点需要注意。


自己实现的类需要提供无参的构造函数

IntentService 是在onHandleIntent中处理耗时操作,这里的intent 就是startService中的intent.

源码分析

我们首先来看一下IntentService 的oncreate的代码


    @Override

    public void onCreate() {

        // TODO: It would be nice to have an option to hold a partial wakelock

        // during processing, and to have a static startService(Context, Intent)

        // method that would launch the service & hand off a wakelock.


        super.onCreate();

        //构造一个IntentService,并启动

        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");

        thread.start();


//使用HandlerThread 的looper 构造一个handler,这样就可以从HandlerThread接收发送消息

        mServiceLooper = thread.getLooper();

        mServiceHandler = new ServiceHandler(mServiceLooper);

    }


HandlerThread中比较值得关注的就是run方法。


    @Override

    public void run() {

        mTid = Process.myTid();

        Looper.prepare();

        synchronized (this) {

            mLooper = Looper.myLooper();

            notifyAll();

        }

        Process.setThreadPriority(mPriority);

        onLooperPrepared();

        Looper.loop();

        mTid = -1;

    }


这里的代码也比较简单,流程基本上就是在非ui thread中构建Handler的标准流程,然后会走到 Looper.loop();中进入死循环。所以HandlerThread在使用结束以后,需要记得调用quit方法,停止死循环。


关注完oncreate方法,我们来着重观察一下IntentServcie的onstart 和 onStartCommand方法


  @Override

    public void onStart(Intent intent, int startId) {

        Message msg = mServiceHandler.obtainMessage();

        msg.arg1 = startId;

        msg.obj = intent;

        mServiceHandler.sendMessage(msg);

    }


    /**

     * You should not override this method for your IntentService. Instead,

     * override {@link #onHandleIntent}, which the system calls when the IntentService

     * receives a start request.

     * @see android.app.Service#onStartCommand

     */

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

        onStart(intent, startId);

        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;

    }


可以看到这里利用了onStartCommand 每次startService每次都会调用onStartCommand的特点,用来给IntentService传递消息。IntentService收到消息后,就会调用mServiceHandler 将消息发送出去。这里主要的作用是将主线程的信息传递到HandlerThread。所以接下来,我们来看下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);

        }

    }


重要的代码,一共就两句话,而onHandleIntent 就是我们需要在自己实现的IntentService中覆写的方法,也就是用来处理耗时事件的方法。

如果处理完onHandleIntent事件以后,service会尝试调用stopSelf去结束掉整个服务。但是这个结束服务并不是一个强制性的操作,如果service仍然有事件未处理,就不会结束掉。这里就不在细究,大家记住这个结论就行了。

而且由于handler的消息阻塞机制,这里的事件并不会并发执行,而是类似SingleThreadExecutor的单任务串行执行。