子線程更新主線程的方法-轉

Android的UI更新只能在UI線程中,即主線程。子線程中若是要進行UI更新,都是要通知主線程來進行。ide

幾種實現方式總結以下,歡迎補充。函數

一、runOnUiThread()oop

子線程中持有當前Activity引用(假如爲Activity mActivity;),便可以調用mActivity的runOnUiThread(Runnable r)方法。post

二、post()和postDelay()this

子線程若是持有某個View的引用,要對該View進行更新,則可調用該View對象的post(Runnable r)或postDelay(Runnable r)方法url

Handler對象也有post()方法。其實在Android的源碼中,這些post()方法都是藉助下面的第3種方法:Handler + Message來實現的。spa

三、Handler + Message或者Handler + Thread + Message線程

主線程創建時,默認狀況下是有Looper的,能夠處理消息隊列。orm

在主線程創建一個Handler對象,複寫其handleMessage()方法,在該方法中實現UI更新。對象

示例:

private static final int MSG_CODE = 1001;
private Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)

{

//接收並處理消息

if(msg.what == MSG_CODE)
{
//UI更新
}
}
};

public void doSomething()
{
new Thread()
{
@Override
public void run()

{

//子線程發送信息

Message msg = mHandler.obtainMessage(MSG_CODE);
msg.sendToTarget();
}
}.start();

}

四、Broadcast

子線程中發送廣播,主線程中接收廣播並更新UI

五、AsyncTask

AsyncTask可方便地實現新開一個線程,並將結果返回給UI線程,而不須要開發者手動去新開一個線程,也無須開發者使用Handler,很是方便。

應當注意的是AsyncTask是一個抽象類,其三個泛型參數的意義以下:
AsyncTask<Param, Progress, Result>
Param:發送給新開的線程的參數類型
Progress:表徵任務處理進度的類型。
Result:線程任務處理完以後,返回給UI線程的值的類型。

該類中有四個抽象函數,onPreExecute(), doInBackground(Params... param),
onProgressUpdate(Progress... progress), onPostExecute(Result result)。
除了,doInBackground(Params...)方法,其它三個方法都運行在UI線程。

自定義一個類繼承AsyncTask並至少實現 doInBackground()函數。在該函數中執行的過程當中,能夠隨時調用publishProgress(Progress...)報告其執行進 度。此時會觸發另外一個方法onProgressUpdate(Progress... progress),以便在UI線程中的某些控件(如ProgressBar)上更新任務處理的進度。

也能夠等doInBackground()執行完,進入onPostExecute()方法後,再進行UI控件的更新。

可在任意時間,任意線程中,取消AsyncTask開啓的任務(調用自定義的AsynTask子類的cancel(boolean mayInterruptIfRunning)方法)

使用示例以下:

//若是沒記錯的話,這個例子應該是以前總結的時候從官網剪下來的

public void onClick(View v) {
   new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
   /** The system calls this to perform work in a worker thread and
     * delivers it the parameters given to AsyncTask.execute() */
   protected Bitmap doInBackground(String... urls) {
       return loadImageFromNetwork(urls[0]);
   }
   
   /** The system calls this to perform work in the UI thread and delivers
     * the result from doInBackground() */
   protected void onPostExecute(Bitmap result) {
       mImageView.setImageBitmap(result);
   }
}

相關文章
相關標籤/搜索