日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java ui线程_UI线程异常处理方法

發(fā)布時間:2025/3/15 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java ui线程_UI线程异常处理方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

UI線程是非線程安全的,所以,不能在工作線程中操作UI元素。

兩個原則

Do not block the UI thread (不要阻塞UI線程)

Do not access the Android UI toolkit from outside the UI thread (不要在工作線程中操作UI元素)

在工作線程更新UI方法

Activity.runOnUiThread(Runnable)

Handler

sendMessage(Message)

post(Runnable)

AsyncTask

execute()

doInBackground()

onPostExecute()

例子程序

HandlerActivity01

在工作線程中進行UI操作。

HandlerActivity02

Handler的兩個重要方法:sendMessage和post。

HandlerActivity03

官方推薦最佳方法。

HandlerActivity01主要代碼:

Java代碼

btnEnd.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

new Thread(new Runnable() {

@Override

public void run()

{

//在新建的線程(工作線程)中改變Button的文字

btnEnd.setText("Text Changed in Sub Thread");

}

}).start();

}

});

這是一種錯誤的做法,運行程序,會報錯誤:

Java代碼

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

HandlerActivity02主要代碼:

Java代碼

public class HandlerActivity02 extends Activity

{

private int title = 0;

Button btnStart,btnEnd;

private Handler mHandler = new Handler()

{

public void handleMessage(Message msg)

{

//更新UI

switch (msg.what)

{

case 1:

updateTitle();

break;

}

};

};

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnStart = (Button)findViewById(R.id.start);

btnEnd = (Button)findViewById(R.id.end);

//新啟動一個線程,進行耗時操作

Timer timer = new Timer();

//每六秒執(zhí)行一次MyTask的run方法

timer.scheduleAtFixedRate(new MyTask(this), 1, 6000);

}

private class MyTask extends TimerTask

{

private Activity context;

MyTask(Activity context)

{

this.context = context;

}

@Override

public void run()

{

//耗時操作略....

//更新UI方法 1

Message message = new Message();

message.what = 1;

mHandler.sendMessage(message);

//更新UI方法 2

mHandler.post(updateThread);

//更新UI方法 3

context.runOnUiThread(updateThread);

}

}

public void updateTitle()

{

setTitle("Welcome to Mr Wei‘s blog " + title);

title++;

}

Runnable updateThread = new Runnable()

{

@Override

public void run()

{

//更新UI

btnStart.setText(String.valueOf(title));

btnEnd.setText(String.valueOf(title));

}

};

}

這里有個容易出錯的地方,在更新UI方法2和3中,我們傳入的參數是一個Runnable對象,一般認為這就會啟動一個新的線程,而且常有人在這個Runnable對象的run方法中進行耗時操作。看過這塊的源碼就會知道,其實,android只是調用了這個Runnable對象的run方法而已,并沒有啟動新的線程,而且我們不應該在run方法中進行耗時操作,因為這個run方法最終是在UI線程里面執(zhí)行的。也就是說,run方法里面只應該放更新UI的代碼,handleMessage方法也一樣。

如果你要看這部分源代碼的話,相信這個圖對你會有幫助:

HandlerActivity03主要代碼:

Java代碼

public class HandlerActivity03 extends Activity

{

Button btnStart;

@Override

protected void onCreate(Bundle savedInstanceState)

{

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnStart = (Button)findViewById(R.id.start);

btnStart.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//開始執(zhí)行AsyncTask,并傳入某些數據

new LongTimeTask().execute("New Text");

}

});

}

private class LongTimeTask extends AsyncTask

{

@Override

protected String doInBackground(String... params)

{

try

{

//線程睡眠5秒,模擬耗時操作,這里面的內容Android系統(tǒng)會自動為你啟動一個新的線程執(zhí)行

Thread.sleep(5000);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

return params[0];

}

@Override

protected void onPostExecute(String result)

{

//更新UI的操作,這里面的內容是在UI線程里面執(zhí)行的

btnStart.setText(result);

}

}

}

這個方法確實挺好,因為它為你封裝了許多操作,你只需要記住在doInBackground方法中寫耗時操作的代碼,在onPostExecute方法中寫更新UI的方法就行了

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結

以上是生活随笔為你收集整理的java ui线程_UI线程异常处理方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。