Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android資訊 >> Android HandlerThread使用總結

Android HandlerThread使用總結

編輯:Android資訊

簡介

首先我們看到HandlerThread很快就會聯想到Handler。Android中Handler的使用,一般都在UI主線程中執行,因此在Handler接收消息後,處理消息時,不能做一些很耗時的操作,否則將出現ANR錯誤。

Android中專門提供了HandlerThread類,來解決該類問題。HandlerThread類是一個線程專門處理Hanlder的消息,依次從Handler的隊列中獲取信息,逐個進行處理,保證安全,不會出現混亂引發的異常。HandlerThread繼承於Thread,所以它本質就是個Thread。與普通Thread的差別就在於,它有個Looper成員變量。

在看看官方的對他的講解

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可以創建一個帶有looper的線程。looper對象可以用於創建Handler類來進行來進行調度。接下來看看HandlerThread的源碼

 package android.os;

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }

    protected void onLooperPrepared() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

線程run()方法當中先調用Looper.prepare()初始化Looper,最後調用Looper.loop(),這樣我們就在該線程當中創建好Looper。(注意:Looper.loop()方法默認是死循環).prepare()呢。

Handler原理

要理解Handler的原理,理解如下幾個概念即可茅塞頓開。

  • Message 意為消息,發送到Handler進行處理的對象,攜帶描述信息和任意數據。
  • MessageQueue 意為消息隊列,Message的集合。
  • Looper 有著一個很難聽的中文名字,消息泵,用來從MessageQueue中抽取Message,發送給Handler進行處理。
  • Handler 處理Looper抽取出來的Message。

Android 異步消息處理機制 讓你深入理解 Looper、Handler、Message三者關系

用法

HandlerThread thread = newHandlerThread("handler_thread");
thread.start();//必須要調用start方法
final Handlerhandler = newHandler(thread.getLooper()){

其他api

//用於返回與該線程相關聯的Looper對象
thread.getLooper();
//獲得該線程的Id
thread.getThreadId();
//結束當前的Looper 循環。
thread.quit();
//用於looper取出的消息處理
thread.run();

實例

效果圖

Android HandlerThread使用總結

在以上效果圖中可以看到當我點擊按鈕之後,兩個藍色的方塊變成了圖片。在按鈕點擊事件中我添加了兩個下載圖片的任務(模擬情況下),並在加載完後替換控件的默認圖片。很明顯很可以看到是有先後順序的。在第一張圖片加載完後第二張圖片才會顯示。

MainActivity

 public class MainActivity extends AppCompatActivity {
    private HandlerThread handlerThread;
    private ImageView imageView,imageView1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }

    private void init() {
        imageView= (ImageView) findViewById(R.id.imageView);
        imageView1= (ImageView) findViewById(R.id.imageView1);

        handlerThread = new HandlerThread("MainActivity");
        handlerThread.start();
        final Handler handler = new Handler(handlerThread.getLooper());

        //點擊download開始進行下載
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handler.post(new MyRunable(1));
                handler.post(new MyRunable(2));
            }
        });
    }

    class MyRunable implements Runnable {
        int pos;

        public MyRunable(int pos) {
            this.pos = pos;
        }

        @Override
        public void run() {
            //模擬耗時
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (pos == 1) {
                imageView.post(new Runnable() {
                    @Override
                    public void run() {
                        imageView.setBackgroundResource(R.mipmap.ic_launcher);
                    }
                });
            } else {
                imageView.post(new Runnable() {
                    @Override
                    public void run() {
                        imageView1.setBackgroundResource(R.mipmap.ic_launcher);
                    }
                });
            }

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        handlerThread.quit();//停止Looper的循環
    }
}

布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 android:paddingBottom="@dimen/activity_vertical_margin"
 android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin"
 tools:context="com.example.handlerthread.MainActivity">

    <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="horizontal">

        <ImageView
 android:id="@+id/imageView"
 android:layout_width="100dp"
 android:layout_height="50dp"
 android:background="@android:color/holo_blue_dark" />

        <ImageView
 android:id="@+id/imageView1"
 android:layout_width="100dp"
 android:layout_height="50dp"
 android:layout_marginLeft="10dp"
 android:background="@android:color/holo_blue_dark" />

    </LinearLayout>

    <Button
 android:id="@+id/button"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="downLoad" />

</LinearLayout>

源碼地址:https://github.com/Waylenw/AndroidBase

總結

HandlerThread適合在只需要在一個工作線程(非UI線程)+任務的等待隊列的形式,優點是不會有堵塞,減少了對性能的消耗,缺點是不能同時進行多任務的處理,需要等待進行處理。處理效率較低。

感謝參考(更多詳細)

http://blog.csdn.net/lmj623565791/article/details/47079737

http://droidyue.com/blog/2015/11/08/make-use-of-handlerthread/?utm_source=tuicool&utm_medium=referral

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved