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


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

幾種實現方式總結如下,歡迎補充。

1、runOnUiThread()

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

2、post()和postDelay()

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

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

3、Handler + Message或者Handler + Thread + Message

主線程建立時,默認情況下是有Looper的,可以處理消息隊列。

在主線程建立一個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();

}

4、Broadcast

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

5、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);
   }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM