Android開發(fā)之子線程操作UI的幾種方法
在Android項目中經(jīng)常有碰到這樣的問題,在子線程中完成耗時操作之后要更新UI,下面就自己經(jīng)歷的一些項目總結一下更新的方法:
在看方法之前需要了解一下Android中的消息機制。
方法1 Activity.runOnUiThread
方法如下:
runOnUiThread(new Runnable() { @Override public void run() { tv.setText("Hello"); } });
這種方法簡單易用,如果當前線程是UI線程,那么行動是立即執(zhí)行。如果當前線程不是UI線程,就發(fā)布到事件隊列的UI線程。其實和Handler差不多,都是將這個更新UI的請求消息,加入到事件隊列,等待主線程空閑的時候執(zhí)行。
方法2 Handler
主線程中定義Handler如下:
Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: String data = (String)msg.obj; textView.setText(data); break; default: break; } } };
子線程發(fā)消息,通知Handler完成UI更新,代碼如下:
new Thread(new Runnable(){ @Override public void run() { //耗時操作 mHandler.sendEmptyMessage(0); Message msg =new Message(); msg.obj = "數(shù)據(jù)";//可以是基本類型,可以是對象,可以是List、map等 mHandler.sendMessage(msg); } }).start();
方法3 View.post
final Button btn =(Button)findViewById(R.id.btn); btn.post(new Runnable(){ @Override publicvoid run() { btn.setText("Hello"); } });
上面的代碼就是更新btn中的內(nèi)容,同樣下面的代碼也可以達到這種效果。
Handler handler = new Handler(); final Button btn = (Button)findViewById(R.id.btn); handler.post(new Runnable(){ @Override public void run() { btn.setText("Hello"); } });
這個是用handler.post方法,一個是用View.post方法,handler.post方法已經(jīng)在Android的消息機制中介紹過了,其實最終也是調(diào)用了方法2中的send方法。
現(xiàn)在看一下View.post方法的源代碼:
public boolean post(Runnable action) { Handler handler; AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { handler = attachInfo.mHandler; } else { // Assume that post will succeed later ViewRootImpl.getRunQueue().post(action); return true; } return handler.post(action); }
方法中主要的功能代碼就是attachInfo.mHandler,獲取當前線程(即UI線程)的Hanlder,然后將action對象post到Handler里。在Handler里的處理過程上面鏈接文已經(jīng)分析的很清楚了,它將傳遞過來的action對象包裝成一個Message(Message的callback為action),然后將其投入UI線程的消息循環(huán)中。在Handler的dispatchMessage方法里,第一句話就是為它所設,直接調(diào)用runnable的run方法。而此時,已經(jīng)路由到UI線程里,因此,我們可以毫無顧慮的來更新UI。
方法4 廣播
子線程中發(fā)送廣播,主線程中接收廣播并更新UI。
方法5 使用AsyncTask
為了簡化子線程中訪問UI,系統(tǒng)提供給了我們AsyncTask。
AsyncTask是一種輕量級的異步任務類,它可以在線程池中執(zhí)行后臺任務,然后把執(zhí)行進度和結果傳遞給主線程并更新UI。本質(zhì)上來說AsyncTask封裝了Thread和Handler,但是AsyncTask不適合進行特別耗時的后臺任務,如果需要進行特別耗時的任務,建議使用線程池。
不同API版本的AsyncTask具有不同的表現(xiàn),因此需要注意。為了控制篇幅,具體的AsyncTask的使用方法和工作原理,我打算后面單獨成文進行介紹。
以上所述是小編給大家介紹的Android開發(fā)之子線程操作UI的幾種方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!
相關文章
flutter實現(xiàn)帶刪除動畫的listview功能
最近接了一個新項目,需要開發(fā)帶有刪除動畫效果的listview功能,在實現(xiàn)過程中列表滾動效果用listview實現(xiàn)的,本文通過實例代碼給大家分享實現(xiàn)過程,感興趣的朋友跟隨小編一起學習下吧2021-05-05Android中GridView和ArrayAdapter用法實例分析
這篇文章主要介紹了Android中GridView和ArrayAdapter用法,結合實例形式分析了Android中GridView結合ArrayAdapter實現(xiàn)表格化排版的相關技巧,需要的朋友可以參考下2016-02-02Android Compose實現(xiàn)底部按鈕以及首頁內(nèi)容詳細過程
這篇文章主要介紹了如何利用compose框架制作app底部按鈕以及首頁內(nèi)容的詳細代碼,具有一定價值,感興趣的可以了解一下2021-11-11Eclipse工程轉(zhuǎn)為兼容Android Studio模式的方法步驟圖文詳解
這篇文章主要介紹了Eclipse工程轉(zhuǎn)為兼容Android Studio模式的方法步驟,本文圖文并茂給大家介紹的非常詳細,需要的朋友可以參考下2017-12-12Android?ScrollView實現(xiàn)滾動超過邊界松手回彈
這篇文章主要為大家詳細介紹了Android?ScrollView實現(xiàn)滾動超過邊界松手回彈,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04Android?ViewPager實現(xiàn)左右滑動翻頁效果
這篇文章主要為大家詳細介紹了Android?ViewPager實現(xiàn)左右滑動翻頁效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12