Android中子執行緒更新主執行緒UI和ProgressBar的應用

君墨痕發表於2013-10-31

很多情況先都需要開啟其他子執行緒,但子執行緒又不能直接更新主線的UI,利用handler可以實現這個需求

1、定義一個標識DOWN_FINISH和new 一個handler並重寫handleMessage方法

2、在子執行緒中Message message=Message.obtain();這樣比直接new一個Message效率更高,應為進度條是一直重新整理,會一直new,而obtain()方式的的解釋是A Message object from the global pool.

直接看程式碼:

public class MainActivity extends Activity implements OnClickListener {

	private Button download;
	private Button pbBtn;
	private EditText et;
	private ProgressBar pb;
	private static final int DOWN_FINISH = 3;
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case DOWN_FINISH:
				pb.setVisibility(View.INVISIBLE);
				Toast.makeText(MainActivity.this, "下載完成", Toast.LENGTH_SHORT)
						.show();
				break;
			default:
				break;
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		pbBtn = (Button) findViewById(R.id.button2);

		pb = (ProgressBar) findViewById(R.id.progressBar1);
		pb.setVisibility(View.INVISIBLE);

		pbBtn.setOnClickListener(this);
	}

	public void tryLoad() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				String url = et.getText().toString().trim();
				String newFileName = url.substring(url.lastIndexOf("/") + 1,
						url.length());
				if (!TextUtils.isEmpty(url)) {
					DownloadUtils.download(url, newFileName, "/sdcard/", 10);
				}
			}
		}).start();

	}

	public void progressBar() {
		pb.setVisibility(View.VISIBLE);
		final int max = 20;
		pb.setMax(max);
		new Thread(new Runnable() {
			int current = 0;
			boolean flag = true;

			@Override
			public void run() {
				while (flag) {
					current++;
					pb.setProgress(current);
					try {
						Thread.sleep(300);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if (current >= max) {
						flag = false;
						Message msg = Message.obtain(handler);
						msg.what = DOWN_FINISH;
						// 這裡是sendMessage方法,而不是自己重寫的handleMessage方法
						handler.sendMessage(msg);
					}
				}
			}
		}).start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if (v == pbBtn) {
			progressBar();
		}
	}
}

效果:

紅色區域是 進度條,因為我這初始化時讓其不可見,點選 PBTest 顯示進度條及進度動畫,進度達到最大值時讓其不可見
呼叫的方法是
pb.setVisibility(View.INVISIBLE);
View.VISIBLE
View.INVISIBLE
View.GONE//如果使用這個,其他控制元件的位置和這個控制元件不要有聯絡,否則佈局會會亂



相關文章