Android使用Thread+Handler實現非UI線程更新介面

來源:互聯網
上載者:User

每個Android應用程式都運行在一個dalvik虛擬機器進程中,進程開始的時候會啟動一個主線程(MainThread),主線程負責處理和ui相關的事件,因此主線程通常又叫UI線程。而由於Android採用UI單執行緒模式,所以只能在主線程中對UI元素進行操作。如果在非UI線程直接對UI進行了操作,則會報錯:CalledFromWrongThreadException:only the original thread that created a view hierarchy can touch its views。Android為我們提供了訊息迴圈的機制,我們可以利用這個機制來實現線程間的通訊。那麼,我們就可以在非UI線程發送訊息到UI線程,最終讓Ui線程來進行ui的操作。對於運算量較大的操作和IO操作,我們需要新開線程來處理這些繁重的工作,以免阻塞ui線程。 ThreadHandlerActivity.activity[java] public class ThreadHandlerActivity extends Activity {      /** Called when the activity is first created. */            private static final int MSG_SUCCESS = 0;//擷取圖片成功的標識      private static final int MSG_FAILURE = 1;//擷取圖片失敗的標識            private ImageView mImageView;      private Button mButton;            private Thread mThread;            private Handler mHandler = new Handler() {          public void handleMessage (Message msg) {//此方法在ui線程運行              switch(msg.what) {              case MSG_SUCCESS:                  mImageView.setImageBitmap((Bitmap) msg.obj);//imageview顯示從網路擷取到的logo                  Toast.makeText(getApplication(), "成功!", Toast.LENGTH_LONG).show();                  break;                case MSG_FAILURE:                  Toast.makeText(getApplication(), "失敗!", Toast.LENGTH_LONG).show();                  break;              }          }      };            @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.threadhandler);          mImageView= (ImageView) findViewById(R.id.threadhandler_imageView);//顯示圖片的ImageView          mButton = (Button) findViewById(R.id.threadhandler_download_btn);          mButton.setOnClickListener(new OnClickListener() {                            @Override              public void onClick(View v) {                  if(mThread == null) {                      mThread = new Thread(runnable);                      mThread.start();//線程啟動                  }                  else {                      Toast.makeText(ThreadHandlerActivity.this, "線程已啟動!", Toast.LENGTH_LONG).show();                  }              }          });      }            Runnable runnable = new Runnable() {                    @Override          public void run() {//run()在新的線程中運行              HttpClient hc = new DefaultHttpClient();              HttpGet hg = new HttpGet("http://pic7.nipic.com/20100517/4945412_113951650422_2.jpg");//擷取指南針圖片              final Bitmap bm;              try {                  HttpResponse hr = hc.execute(hg);                  bm = BitmapFactory.decodeStream(hr.getEntity().getContent());              } catch (Exception e) {                  mHandler.obtainMessage(MSG_FAILURE).sendToTarget();//擷取圖片失敗                  return;              }              mHandler.obtainMessage(MSG_SUCCESS,bm).sendToTarget();//擷取圖片成功,向ui線程發送MSG_SUCCESS標識和bitmap對象          }      };        }   threadhandler.xml [html]  <?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="fill_parent"      android:layout_height="fill_parent"      android:orientation="vertical" >        <Button          android:id="@+id/threadhandler_download_btn"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="ThreadHandler下載" >      </Button>        <ImageView          android:id="@+id/threadhandler_imageView"          android:layout_width="wrap_content"          android:layout_height="wrap_content" />    </LinearLayout>   運行結果:  非UI線程發送訊息到UI線程分為兩個步驟一、發送訊息到UI線程的訊息佇列通過使用Handler的Message obtainMessage(int what,Object object)構造一個Message對象,這個Object Storage Service了是否成功擷取圖片的標識what和bitmap對象,然後通過message.sendToTarget()方法把這條message放到訊息佇列中去。二、處理髮送到UI線程的訊息在ui線程中,我們覆蓋了handler的 public void handleMessage (Message msg) 這個方法是處理分發給ui線程的訊息,判斷msg.what的值可以知道mThread是否成功擷取圖片,如果圖片成功擷取,那麼可以通過msg.obj擷取到這個對象。最後,我們通過mImageView.setImageBitmap((Bitmap) msg.obj);設定ImageView的bitmap對象,完成UI的更新。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.