android HandlerThread使用

本文详细解析了HandlerThread在Android开发中的作用及用法。通过对比主线程与子线程中的Handler行为,介绍了如何利用HandlerThread避免主线程阻塞,并提供了一个具体的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  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的作用和用法了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值