Android HandlerThread使用總結
簡介
首先我們看到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();
例項
效果圖
在以上效果圖中可以看到當我點選按鈕之後,兩個藍色的方塊變成了圖片。在按鈕點選事件中我新增了兩個下載圖片的任務(模擬情況下),並在載入完後替換控制元件的預設圖片。很明顯很可以看到是有先後順序的。在第一張圖片載入完後第二張圖片才會顯示。
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
相關文章
- Android中HandlerThread的使用及原始碼解析Androidthread原始碼
- Android View 使用總結AndroidView
- Android ViewPager 的使用總結AndroidViewpager
- Android中文API(128) —— HandlerThreadAndroidAPIthread
- Android 中的 HandlerThread 詳解Androidthread
- Android ShareUserId 使用總結Android
- Android 進階之HandlerThread 使用場景及原始碼解析Androidthread原始碼
- 終止Android中HandlerThread的方法Androidthread
- HandlerThread的使用以及原理thread
- 在 Android 中使用 JNI 的總結Android
- Android Studio 快捷鍵使用總結Android
- Android後臺任務(HandlerThread、AsyncTask、IntentService)AndroidthreadIntent
- Android混合開發之WebView使用總結AndroidWebView
- Android 夜間模式庫 changeskin 使用總結Android模式
- Android ORM 框架 greenDAO 使用經驗總結AndroidORM框架
- android webview總結AndroidWebView
- Android面試總結Android面試
- Android 總結 bookAndroid
- Android總結1Android
- Android View總結AndroidView
- Android的Paint、Canvas和Path基本使用總結AndroidAICanvas
- Android中使用WebView遇到的問題總結:AndroidWebView
- 關於Android Studio使用Git的總結AndroidGit
- Android的程式與執行緒使用總結Android執行緒
- 關於Android中使用Enum的一點總結Android
- Android執行緒管理之Thread使用總結Android執行緒thread
- Android Studio除錯功能使用總結【轉】Android除錯
- Android中Service總結Android
- Android面試最新總結Android面試
- Android Handler面試總結Android面試
- android 面試題總結Android面試題
- android WebView總結(轉)AndroidWebView
- 理解 HandlerThread 原理thread
- Android總結篇系列:Android ServiceAndroid
- Android Webview和ScrollView衝突和WebView使用總結AndroidWebView
- 使用Jenkins自動構建Android問題總結JenkinsAndroid
- SVN使用總結
- Git 使用總結Git