Android-HandlerThread详解

本文详细解析了HandlerThread的工作原理和使用方法,包括其在内存管理、降低主线程压力、消息循环等方面的优势。同时,提供了HandlerThread的使用模板,并强调了在实际应用中需要注意的点,如任务执行的串行性和可能的延迟问题。

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

HandlerThread详解

抛砖引玉

在说HandlerThread之前,先看下这个。

mHandler.removeCallbacksAndMessages(null);

进去这个函数看下

    public final void removeCallbacksAndMessages(Object token) {
        mQueue.removeCallbacksAndMessages(this, token);
    }

在到MessageQueue中看下removeCallbacksAndMessages(this, token)这个函数。

    void removeCallbacksAndMessages(Handler h, Object object) {
        if (h == null) {
            return;
        }

        synchronized (this) {
            Message p = mMessages;

            // Remove all messages at front.
            while (p != null && p.target == h
                    && (object == null || p.obj == object)) {
                Message n = p.next;
                mMessages = n;
                p.recycleUnchecked();
                p = n;
            }

            // Remove all messages after front.
            while (p != null) {
                Message n = p.next;
                if (n != null) {
                    if (n.target == h && (object == null || n.obj == object)) {
                        Message nn = n.next;
                        n.recycleUnchecked();
                        p.next = nn;
                        continue;
                    }
                }
                p = n;
            }
        }
    }

可以看到如果参数为null的话,会将所有的Callbacks和Messages全部清除掉。

这样做的好处是在Acticity退出的时候,可以避免内存泄露。所以在退出Activity退出的时候,注意在onDestory中

mHandler.removeCallbacksAndMessages(null);

防止内存泄露。


HandlerThread优势在哪里?

Handler机制的分发中心就在Looper中的loop(),HandlerThread将loop转到子线程中处理,降低了主线程的压力,使主界面更流畅 。

在子线程中调用Looper.prepare() 为一个线程开启一个消息循环,默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。 然后通过Looper.loop() 让Looper开始工作,从消息队列里取消息,处理消息。

HandlerThread的使用模板

private static H mScanpackagehandler;



//创建HandlerThread
 HandlerThread thread = new HandlerThread("ProxyThread");
        thread.start();
        //创建Handler
        mScanpackagehandler = new H(thread.getLooper());
   
   
   //发送信息1
    Message message = mScanpackagehandler.obtainMessage();
                message.what = SCAN_PAGE;
                message.obj = packageName;
  mScanpackagehandler.sendMessage(message);//发送message
  
   //发送信息2
  Message message = mScanpackagehandler.obtainMessage();
                message.what = SCAN_PAGE1;
                message.obj = packageName1;
  mScanpackagehandler.sendMessage(message);//发送message
  
  
  //依次从MessageQueu中取数据
  
 private class H extends Handler {
        public H(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case SCAN_PAGE:
            ...
            break;
            case SCAN_PAGE1:
            ...
            brea;
            default:
            break;
                
            }
        }
    }
    
    
       //在onDestory的时候清除MessageQueue中的数据
    public void onDestroy() {
        super.onDestroy();
         //释放资源
        mScanpackagehandler.quit();
        
    }

举个栗子

eg.额,代码不太规范啊,就那么个意思。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button mStartButton;
    private TextView mTextView;
    private Handler mHandler;
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStartButton = (Button) findViewById(R.id.button);
        mStartButton.setOnClickListener(this);
        mTextView = (TextView) findViewById(R.id.textView);
        Log.d(TAG, "thread.name3:" + Thread.currentThread().getName());
        initHandlerThread();
        Message msg = mHandler.obtainMessage();
        msg.arg1 = 2;
        mHandler.sendMessage(msg);

    }

    private void initHandlerThread() {
        HandlerThread hthread = new HandlerThread("HandlerThread1");
        hthread.start();
        mHandler = new H(hthread.getLooper());


    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button:
                Message msg = mHandler.obtainMessage();
                msg.arg1 = 1;
                mHandler.sendMessage(msg);
                break;
            default:
                break;
        }

    }

    public class H extends Handler {
        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.arg1) {
                case 1:
                    Log.d(TAG, "thread.name1:" + Thread.currentThread().getName());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.d(TAG, "thread.name11:" + Thread.currentThread().getName());
                            mTextView.setText("HandlerThread1");
                        }
                    });
                    break;
                case 2:
                    Log.d(TAG, "thread.name2:" + Thread.currentThread().getName());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.d(TAG, "thread.name22:" + Thread.currentThread().getName());
                            mTextView.setText("HandlerThread11");
                        }
                    });
                    break;
                default:
                    break;

            }
        }
    }
}

HandlerThread的几点注意

HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。

开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。

但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。

HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。

对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值