導航:首頁 > 操作系統 > android子線程更新ui

android子線程更新ui

發布時間:2022-02-24 15:12:54

❶ 如何在android一條單獨線程,更新ui

方法有兩種:
通過繼承Thread類,重寫Run方法來實現
通過繼承介面Runnable實現多線程
主要接受子線程發送的數據, 並用此數據配合主線程更新UI.

Handler的主要作用:主要用於非同步消息的處理

Handler的運行過程:
當(子線程)發出一個消息之後,首先進入一個(主線程的)消息隊列,發送消息的函數即刻返回,而在主線程中的Handler逐個的在消息隊列中將消息取出,然後對消息進行處理。這樣就實現了跨線程的UI更新(實際上還是在主線程中完成的)。
這種機制通常用來處理相對耗時比較長的操作,如訪問網路比較耗時的操作,讀取文大文件,比較耗時的操作處理等。

在大白話一點的介紹它的運行過程:
啟動應用時Android開啟一個主線程
(也就是UI線程) , 如果此時需要一個耗時的操作,例如:
聯網讀取數據,或者讀取本地較大的一個文件的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,界面會出現假死現象(這也就是你在主線程中直接訪問網路時會提示你異常的原因,如我們上篇文章所述Android主線程不能訪問網路異常解決辦法)。

❷ android studio子線程更新UI 問題

  1. 睡使用Thread.currentthread().sleep(1000);

  2. 發送不同的Message,每次都是一個,放到for循環內Message message = new Message();

❸ 在Android子線程中初始化handler後,為什麼該子線程也能更新UI(大神請進)

子線程的hanlder裡面是不能更新Android UI的。


簡單說下:


  1. 如果你在子線程裡面創建hander是用的是以下代碼:

    new Handler(Looper.getMainLooper())

    那還是用的主線程的Looper

❹ android通過Handler使子線程更新UI

在Android項目中經常有碰到這樣的問題,在子線程中完成耗時操作之後要更新UI,下面就自己經歷的一些項目總結一下更新的方法。

一. 引言

首先來看一下android中消息機制:

專業術語:

Message:消息,其中包含了消息ID,消息處理對象以及處理的數據等,由MessageQueue統一列隊,終由Handler處理。
Handler:處理者,負責Message的發送及處理。使用Handler時,需要實現handleMessage(Message msg)方法來對特定的Message進行處理,例如更新UI等。
MessageQueue:消息隊列,用來存放Handler發送過來的消息,並按照FIFO規則執行。當然,存放Message並非實際意義的保存,而是將Message以鏈表的方式串聯起來的,等待Looper的抽取。
Looper:消息泵,不斷地從MessageQueue中抽取Message執行。因此,一個MessageQueue需要一個Looper。
Thread:線程,負責調度整個消息循環,即消息循環的執行場所。

二. 方法

1. 用Handler

(1)主線程中定義Handler:

java代碼:

[java]view plain

HandlermHandler=newHandler(){

@Override

publicvoidhandleMessage(Messagemsg){

super.handleMessage(msg);

switch(msg.what){

case0:

<spanstyle="color:#009900;">//完成主界面更新,拿到數據</span>

Stringdata=(String)msg.obj;

updateWeather();

textView.setText(data);

break;

default:

break;

}

}

};

(2)子線程發消息,通知Handler完成UI更新:

java代碼:

privatevoipdateWeather(){

newThread(newRunnable(){

@Override

publicvoidrun(){

<spanstyle="color:#009900;">//耗時操作,完成之後發送消息給Handler,完成UI更新;</span>

mHandler.sendEmptyMessage(0);

<spanstyle="color:#33cc00;">//需要數據傳遞,用下面方法;</span>

Messagemsg=newMessage();

msg.obj="數據";<spanstyle="color:#33cc00;">//可以是基本類型,可以是對象,可以是List、map等;</span>

mHandler.sendMessage(msg);

}

}).start();

}

注意:Handler對象必須定義在主線程中,如果是多個類直接互相調用,就不是很方便,需要傳遞content對象或通過介面調用。

2.用Activity對象的runOnUiThread方法更新

在子線程中通過runOnUiThread()方法更新UI:

java代碼:

newThread(){

publicvoidrun(){

<spanstyle="color:#009900;">//這兒是耗時操作,完成之後更新UI;</span>

runOnUiThread(newRunnable(){

@Override

publicvoidrun(){

<spanstyle="color:#009900;">//更新UI</span>

imageView.setImageBitmap(bitmap);

}

});

}

}.start();

如果在非上下文類中,可以通過傳遞上下文實現調用:

java代碼:

Activityactivity=(Activity)imageView.getContext();

activity.runOnUiThread(newRunnable(){

@Override

publicvoidrun(){

imageView.setImageBitmap(bitmap);

}

});

注意:這種方法使用比較靈活,但如果Thread定義在其他地方,需要傳遞Activity對象。


3.
View.post(Runnable r)

java代碼:

imageView.post(newRunnable(){

@Override

publicvoidrun(){

imageView.setImageBitmap(bitmap);

}

});

這種方法更簡單,但需要傳遞要更新的View過去。

總結:UI的更新必須在主線程中完成,所以不管上述那種方法,都是將更新UI的消息發送到了主線程的消息對象,讓主線程做處理。

❺ Android 可以通過子線程直接更新的控制項有哪些,UI線程與主線程真是一個神奇的東西,求高手~~

先給你提示一下。android中更新UI只能用UI線程,即主線程。 這樣說吧 ui線程== 主線程。

1 想要在子線程中數據發生改變更新主線程的ui,可以通過消息機制,message和handler結合的方式,比較好用。
2 還可以 用特定的控制項的方法,比如ListView的adapter中的notifydatachang().好像是這個方法
3 在view中還可以在數據變化後用invalidata()或者postInvalidata()這兩個方法。

基本上就這幾種常見的,希望可以幫你,大家都來討論。

❻ android中在子線程中更新UI的幾種方法

照搬一個我自己的回答
..com/question/1822980438413918108

public class passWebViewInNewThread{ static android.os.Handler h=null; static WebView w=null; public static void getWebView(WebView w0){//有點想不起來webview的類名是啥了,強答 w=w0; h=new android.os.Handler();//請用UI線程來運行這段代碼 } public static void doWithWebView(){ new Thread() {//開新線程 @Override public void run() { try {//裡面寫新線程執行內容 /* XXX 耗時內容…… */ h.post(new Runnable(){//用handler轉交UI處理操作 @Override public void run(){ //在這寫操作webview的代碼 //請不要在這里放耗時代碼,否則會卡住UI線程 } }); }catch(Exception e){ } } }.start(); }}//PS:因為我已經不記得如果對象聲明在方法內部如何用final,所以索性寫成這樣。沒環境寫JAVA,所以可能有幾個小錯誤

❼ 如果在Android 子線程中更新ui

針對於b情況,你嘗試下在類中新建一個thread,然後在button的setOnClickListener中調用,應改沒有問題。如果在button的setOnClickListener,應該算是內部類了。

❽ android怎麼樣在子線程實例化的handler去更新UI

之前用過android-async-http,雖然沒認真看過源碼,但也有簡單的瀏覽過,心裡一直有個疑問,因為android-async-http也是採用hanlder機制來執行回調的,也就是說handler是它實例化的,可我們知道handler的一個重要作用是將一個任務切換到handler所在的線程去執行的,我的疑問就是:如果我們在子線程調用android-async-http的網路請求,這時候如果handler是在子線程被實例化的呢(當然我沒認真研究過源碼,也不知道它是怎麼實現),還能更新UI嗎?
我們都正常以為handler在哪個線程實例化的,我們通過handler就可以把任務切換到該任務去執行,我們看如下代碼:

private void initd() {

new Thread(new Runnable() {

@Override

public
void run() {

Looper.prepare();

Handler handler = new
Handler() {

@Override

public void handleMessage(Message msg) {

Toast.makeText(MainActivity.this, "測試子線程彈出toast",
Toast.LENGTH_LONG).show();

((TextView)findViewById(R.id.main_tv_text)).setText("測試子線程");

}

};

Looper.loop();

handler.sendEmptyMessage(0);

}

}).start();

}

經過我的測試上面這段方法是無法更新UI的,因為handler是在子線程實例化的,並非在UI線程,也證實了我們的想法。

如果我的疑問存在(我沒嘗試過在子線程使用android-async-http,不知道什麼情況,這里只是做個假設),那麼它使怎麼實現的呢。

最近看了android開發藝術探索,特意去研究了一下android的消息機制,才弄明白了Handler的工作原理,其實起關鍵作用的是Looper並不是handler,我們先來看下Looper的構造方法:

private Looper(boolean quitAllowed) {

mQueue = new MessageQueue(quitAllowed);

mThread = Thread.currentThread();

}

Looper會把所在的當前的線程保存起來,而handler的工作需要Looper,於是我嘗試了一下如下代碼:

private void init() {

new Thread(new Runnable() {

@Override

public
void run() {

Handler handler = new
Handler(Looper.getMainLooper()) {

@Override

public void handleMessage(Message msg) {

Toast.makeText(MainActivity.this, "測試子線程彈出toast",
Toast.LENGTH_LONG).show();

((TextView)findViewById(R.id.main_tv_text)).setText("測試子線程");

}

};

handler.sendEmptyMessage(0);

}

}).start();

}

handler實例化的時候,我傳入的是UI線程的Looper,確實是可以更新UI。

總結:

1、handler執行任務不是在它實例化所在的線程決定的,而是關鍵在於Looper。

2、我們可以在子線程實例化handler並且可以用它來更新UI了。

❾ android 線程中怎麼更新ui進度條

如果你用的是標準的ProgressBar類,那麼調用setProgress(int progress)方法進行更新即可。
不過如果載入處理不是在UI線程,那就需要用Handler去更新了
舉例如下:
int progress = calculateProgress();
ProgressBar progressBar = mActivity.getProgressBar();
// 獲取主線程Handler。需要編寫getHandler()方法
Handler handler = mActivity.getHandler();
handler.post(new Runnable() {
void run() {
progressBar.setProgress(progress);
}
})

❿ 在多線程中,子線程更新主線程ui有哪些方法及注意點

Android

UI多線程Androidthread工作

在一個Android 程序開始運行的時候,會單獨啟動一個Process。默認的情況下,所有這個程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的兩種,除此之外還有Content Provider和Broadcast Receiver)都會跑在這個Process。

一個Android 程序默認情況下也只有一個Process,但一個Process下卻可以有許多個Thread。在這么多Thread當中,有一個Thread,我們稱之為UI Thread。UI Thread在Android程序運行的時候就被創建,是一個Process當中的主線程Main Thread,主要是負責控制UI界面的顯示、更新和控制項交互。在Android程序創建之初,一個Process呈現的是單線程模型,所有的任務都在一個線程中運行。因此,我們認為,UI Thread所執行的每一個函數,所花費的時間都應該是越短越好。而其他比較費時的工作(訪問網路,下載數據,查詢資料庫等),都應該交由子線程去執行,以免阻塞主線程。

那麼,UI Thread如何和其他Thread一起工作呢?常用方法是:

誕生一個主線程的Handler物件,當做Listener去讓子線程能將訊息Push到主線程的Message Quene里,以便觸發主線程的handlerMessage()函數,讓主線程知道子線程的狀態,並在主線程更新UI。

例如,在子線程的狀態發生變化時,我們需要更新UI。如果在子線程中直接更新UI,通常會拋出下面的異常:11-07 13:33:04.393: ERROR/JavaBinder(1029):android.view.ViewRoot$:Only the original thread that created a view hierarchy can touch its views.

意思是,無法在子線程中更新UI。為此,我們需要通過Handler物件,通知主線程Ui Thread來更新界面。

如下,首先創建一個Handler,來監聽Message的事件:

private final int UPDATE_UI = 1;private Handler mHandler = new MainHandler();private class MainHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE_UI: {Log.i("TTSDeamon", "UPDATE_UI");showTextView.setText(editText.getText().toString());ShowAnimation();break;}default:break;}}}

或者

private Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE_UI: {Log.i("TTSDeamon", "UPDATE_UI");showTextView.setText(editText.getText().toString());ShowAnimation();break;}default:break;}}}

當子線程的狀態發生變化,則在子線程中發出Message,通知更新UI。

mHandler.sendEmptyMessageDelayed(UPDATE_UI, 0);

在我們的程序中,很多Callback方法有時候並不是運行在主線程當中的,所以如果在Callback方法中更新UI失敗,也可以採用上面的方法。

閱讀全文

與android子線程更新ui相關的資料

熱點內容
實數四則運演算法則概念 瀏覽:294
cs16優化命令 瀏覽:869
Minecraft雲伺服器免費 瀏覽:826
png壓縮最小 瀏覽:180
老韓綜app怎麼看不了了 瀏覽:227
只有一個程序員的體驗 瀏覽:321
用伺服器地址怎麼有網 瀏覽:550
路由器伺服器昵稱是什麼 瀏覽:715
程序員男友消失了 瀏覽:401
程序員搜索框自動提示 瀏覽:28
android44api20 瀏覽:677
adb刷recovery命令 瀏覽:697
廣聯達正版加密鎖可以補辦嗎 瀏覽:945
java程序員一天多少行代碼 瀏覽:948
喪屍危機java 瀏覽:125
華為手機怎麼去除app標記未讀信息 瀏覽:856
java監控文件夾 瀏覽:807
群控伺服器主機怎麼轉變普通電腦 瀏覽:707
手機怎麼調整app大小 瀏覽:455
加密門禁卡揭秘 瀏覽:139