android HandlerThread使用

来源:互联网 发布:小米 手机网络不佳 编辑:程序博客网 时间:2024/05/17 08:26

  Handler创建时如果没有给定Looper,那他会与主线程的Looper相关联,也就是默认运行在主线程中,在主线程中可以进行UI更新操作。但是如果Handler处理的内容不涉及UI更新等,同时又是一个非常耗时的操作, 那就会造成阻塞,我们有必要将这些操作在子线程中运行。android提供了HandlerThread方便了这个过程,官方文档对这个类的描述:

Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

  HandlerThread继承Thread,它其实就是一个Thread,只是封装了一个Looper,这个Looper和一个子线程相关联。
  现在分析一下代码:
  使用HandlerThread时必须先要调用start()方法,随后就会调用run()方法,查看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;    }

  上面代码中,Looper.prepare()方法创建了Looper,查看Looper的创建代码:

private Looper(boolean quitAllowed) {        mQueue = new MessageQueue(quitAllowed);        mThread = Thread.currentThread();}

  这里创建了Looper并且当前Looper和当前的线程相关联,也就是说该Looper不在主线程中。我们可以通过HandlerThread.getLooper() 方法获取Looper对象。
  现在回到run()方法,有一个onLooperPrepared()方法,这是一个空方法,我们可以重写该方法。run()方法中随后Looper开启消息循环

  现在看一下下面的代码:

public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private static final int UPDATE_UI = 1;    private MyHandler mMyHandler;    private HandlerThread mHandlerThread;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mMyHandler = new MyHandler();        changeView();        Log.i(TAG, "now thread = " + Thread.currentThread());    }    private void changeView() {        new Thread(new Runnable() {            @Override            public void run() {                Message message = Message.obtain(mMyHandler);                message.obj = 1;                message.sendToTarget();                Log.i(TAG, "now thread = " + Thread.currentThread());            }        }).start();    }    private class MyHandler extends Handler {        public MyHandler() {            super();        }        public MyHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            Log.i(TAG, "now thread = " + Thread.currentThread());        }    }}

  在onCreate()、子线程、和mMyhandler中打印运行的线程,看一下效果:打印日志1
  可以看到默认创建的Handler的handleMessage()方法在主线程中运行。 现在借助HandlerThread创建Handler:

public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private static final int UPDATE_UI = 1;    private MyHandler mMyHandler;    private HandlerThread mHandlerThread;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mHandlerThread = new HandlerThread("handler thread");        mHandlerThread.start();        mMyHandler = new  MyHandler(                mHandlerThread.getLooper());        changeView();        Log.i(TAG, "now thread = " + Thread.currentThread());    }    private void changeView() {        new Thread(new Runnable() {            @Override            public void run() {                Message message = Message.obtain(mMyHandler);                message.obj = 1;                message.sendToTarget();                Log.i(TAG, "now thread = " + Thread.currentThread());            }        }).start();    }    private class MyHandler extends Handler {        public MyHandler() {            super();        }        public MyHandler(Looper looper) {            super(looper);        }        @Override        public void handleMessage(Message msg) {            Log.i(TAG, "now thread = " + Thread.currentThread());        }    }}

  打印日志:
打印日志2
  可以看到创建Handler时制定了Looper,此时Handler的handleMessage()方法在Looper所在的线程运行,而不是在主线程中。

  通过上面的分析和例子,应该可以理解HandlerThread的作用和用法了。

0 0
原创粉丝点击