老問題:Android子執行緒中更新UI的3種方法

鴨脖發表於2015-03-19

在Android專案中經常有碰到這樣的問題,在子執行緒中完成耗時操作之後要更新UI,下面就自己經歷的一些專案總結一下更新的方法:

方法一:用Handler

1、主執行緒中定義Handler:

Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case 0:
				//完成主介面更新,拿到資料
				String data = (String)msg.obj;
				
				updateWeather();
				textView.setText(data);
				break;
			default:
				break;
			}
		}

	};

2、子執行緒發訊息,通知Handler完成UI更新:

private void updateWeather() {
		
		
		new Thread(new Runnable(){

			@Override
			public void run() {
				//耗時操作,完成之後傳送訊息給Handler,完成UI更新;
				mHandler.sendEmptyMessage(0);
				
				//需要資料傳遞,用下面方法;
				Message msg =new Message();
				msg.obj = "資料";//可以是基本型別,可以是物件,可以是List、map等;
				mHandler.sendMessage(msg);
			}
			
		}).start();
		
	}

方法一的Handler物件必須定義在主執行緒中,如果是多個類直接互相呼叫,就不是很方便,需要傳遞content物件或通過介面呼叫;

方法二:用runOnUiThread更新

在子執行緒中通過runOnUiThread()方法更新UI:

new Thread() {
			public void run() {
				//這兒是耗時操作,完成之後更新UI;
				runOnUiThread(new Runnable(){

					@Override
					public void run() {
						//更新UI
						imageView.setImageBitmap(bitmap);
					}
					
				});
			}
		}.start();

如果在非上下文類中(Activity),可以通過傳遞上下文實現呼叫;

Activity activity = (Activity) imageView.getContext();
				activity.runOnUiThread(new Runnable() {

					@Override
					public void run() {
						imageView.setImageBitmap(bitmap);
					}
				});

這種方法使用比較靈活,但如果Thread定義在其他地方,需要傳遞Activity物件;

方法三:View.post(Runnable r)

imageView.post(new Runnable(){

					@Override
					public void run() {
						imageView.setImageBitmap(bitmap);
					}
					
				});

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

相關文章