Android中多線程編程(三)Handler更新UI的方式,android多線程編程
Handler更新UI的方式和原因以及遇到的問題
1.方式:
只能通過Handler來更新UI。
代碼如下:
package com.chengdong.su.handlerdemo;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;/** * android中更新UI的方式 * * @author scd * */public class SixActivity extends Activity { private String TAG = getClass().getSimpleName(); private String mName = "HandlerThread"; private TextView mView; /** the object of the Handler */ private Handler mHandler = new Handler() { public void handleMessage(Message msg) { Log.d(TAG, "------>handleMessage() 主線程:" + Thread.currentThread()); mView.setText("主線程02"); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); Log.d(TAG, "------>onCreate() 主線程:" + Thread.currentThread()); new Thread() { public void run() { try { Thread.sleep(2000); Log.d(TAG, "------>Thread() 子線程:" + Thread.currentThread()); // updateUI01(); // updateUI02(); // updateUI03(); updateUI04(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); } /** * init the view */ private void init() { mView = (TextView) findViewById(R.id.textView1); } /** * 更新UI的方式1 */ public void updateUI01() { Log.d(TAG, "------>updateUI01() Thread() 子線程:" + Thread.currentThread()); mHandler.post(new Runnable() { @Override public void run() { Log.d(TAG, "------>updateUI01() Thread() run() 主線程:" + Thread.currentThread()); mView.setText("主線程01"); } }); } /** * 更新UI的方式2 */ public void updateUI02() { Log.d(TAG, "------>updateUI02() Thread() 子線程:" + Thread.currentThread()); mHandler.sendEmptyMessage(0); } /** * 更新UI的方式3 */ public void updateUI03() { Log.d(TAG, "------>updateUI03() Thread() 子線程:" + Thread.currentThread()); // 更新UI介面中的組件 runOnUiThread(new Runnable() { @Override public void run() { Log.d(TAG, "------>updateUI03() Thread() run() 主線程:" + Thread.currentThread()); mView.setText("主線程03"); } }); } /** * 更新UI的方式4 */ public void updateUI04() { Log.d(TAG, "------>updateUI04() Thread() 子線程:" + Thread.currentThread()); mView.post(new Runnable() { @Override public void run() { Log.d(TAG, "------>updateUI04() Thread() run() 主線程:" + Thread.currentThread()); mView.setText("主線程04"); } }); }}
推薦使用第一種和第二種。
2.使用Handler更新UI的原因:
如果當前線程和主線程不相等的話,更新UI就會拋出異常。
Activity檢查當前線程和主線程是否相等是在onResume()方法才開始的。
所以在新開啟的線程,如果不休眠直接更新UI的話不會拋出異常。
如果休眠再做更新UI操作的話就會拋出異常。
例子如下:(不要這樣使用,只是為了示範說明)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); Log.d(TAG, "------>onCreate() 主線程:" + Thread.currentThread()); new Thread() { public void run() { // 不會出現異常 // mView.setText("主線程02"); try { Thread.sleep(2000); // 出現異常 mView.setText("主線程02"); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); }
3. Android開發中Handler的使用遇到的問題:
1.不能在子線程中更新UI。
2.如果在子線程建立Handler的時候,一定要建立一個Looper對象:Looper.prepare();
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。