如图,Android上新开的线程如想更新UI,需要重新跳到主线程中才能操作,以下是老外给出的几种方案,大家多多学习下.
1通过UI控件post一个runnable子类:
private void loadIcon() { new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(mDelay); } catch (InterruptedException e) { e.printStackTrace(); } mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.painter); mImageView.post(new Runnable() { @Override public void run() { mImageView.setImageBitmap(mBitmap); } }); } }).start(); }
2.通过调用主线程runOnUiThread执行修改
new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(mDelay); } catch (InterruptedException e) { e.printStackTrace(); } mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.painter); SimpleThreadingExample.this.runOnUiThread(new Runnable() { @Override public void run() { mImageView.setImageBitmap(mBitmap); } }); } }).start();
3.通过Handler不断的在另一条线程上post一个runnable来执行修改:
private class LoadIconTask implements Runnable { int resId; LoadIconTask(int resId) { this.resId = resId; } public void run() { handler.post(new Runnable() { @Override public void run() { mProgressBar.setVisibility(ProgressBar.VISIBLE); } }); mBitmap = BitmapFactory.decodeResource(getResources(), resId); // Simulating long-running operation for (int i = 1; i < 11; i++) { sleep(); final int step = i; handler.post(new Runnable() { @Override public void run() { mProgressBar.setProgress(step * 10); } }); } handler.post(new Runnable() { @Override public void run() { mImageView.setImageBitmap(mBitmap); } }); handler.post(new Runnable() { @Override public void run() { mProgressBar.setVisibility(ProgressBar.INVISIBLE); } }); } }
4.以下的例子通过Handlemessage来做操作,比较有意思的是采用了软引用.(参考IOS中的weak关键字),同时handler发送message的时候obtainMessage采用了池的回收机制.
static class UIHandler extends Handler { WeakReference<HandlerMessagesActivity> mParent; public UIHandler(WeakReference<HandlerMessagesActivity> parent) { mParent = parent; } @Override public void handleMessage(Message msg) { HandlerMessagesActivity parent = mParent.get(); if (null != parent) { switch (msg.what) { case SET_PROGRESS_BAR_VISIBILITY: { parent.getProgressBar().setVisibility((Integer) msg.obj); break; } case PROGRESS_UPDATE: { parent.getProgressBar().setProgress((Integer) msg.obj); break; } case SET_BITMAP: { parent.getImageView().setImageBitmap((Bitmap) msg.obj); break; } } } } } Handler handler = new UIHandler(new WeakReference<HandlerMessagesActivity>( this)); private class LoadIconTask implements Runnable { private final int resId; private final Handler handler; LoadIconTask(int resId, Handler handler) { this.resId = resId; this.handler = handler; } public void run() { Message msg = handler.obtainMessage(SET_PROGRESS_BAR_VISIBILITY, ProgressBar.VISIBLE); handler.sendMessage(msg); final Bitmap tmp = BitmapFactory.decodeResource(getResources(), resId); for (int i = 1; i < 11; i++) { sleep(); msg = handler.obtainMessage(PROGRESS_UPDATE, i * 10); handler.sendMessage(msg); } msg = handler.obtainMessage(SET_BITMAP, tmp); handler.sendMessage(msg); msg = handler.obtainMessage(SET_PROGRESS_BAR_VISIBILITY, ProgressBar.INVISIBLE); handler.sendMessage(msg); } private void sleep() { try { Thread.sleep(mDelay); } catch (InterruptedException e) { e.printStackTrace(); } } }
5.采用AyncTask方式,也是我们比较常用的方式
class LoadIconTask extends AsyncTask<Integer, Integer, Bitmap> { @Override protected void onPreExecute() { mProgressBar.setVisibility(ProgressBar.VISIBLE); } @Override protected Bitmap doInBackground(Integer... resId) { Bitmap tmp = BitmapFactory.decodeResource(getResources(), resId[0]); // simulating long-running operation for (int i = 1; i < 11; i++) { sleep(); publishProgress(i * 10); } return tmp; } @Override protected void onProgressUpdate(Integer... values) { mProgressBar.setProgress(values[0]); } @Override protected void onPostExecute(Bitmap result) { mProgressBar.setVisibility(ProgressBar.INVISIBLE); mImageView.setImageBitmap(result); } private void sleep() { try { Thread.sleep(mDelay); } catch (InterruptedException e) { Log.e(TAG, e.toString()); } } }
不管如何.发这东西,只是想表达下 ,老外的东西有时候还是蛮有意思的.
时间: 2024-11-08 18:24:53