1. 程式人生 > >學習筆記(七)多執行緒開發

學習筆記(七)多執行緒開發

相信大家在Java中都已經接觸過執行緒,就是像一條線一樣一次執行相關的操作,特點就是同步的,順序進行的。
但是,Android和Java的執行緒有一點區別在於就是在子執行緒中不能對UI元件進行相關操作,Android中的所有元件的操作要求在主執行緒(UI執行緒)中進行。如果我們在主執行緒中進行過多的耗時操作,有可能導致執行緒卡死,超過5s,程式就會被系統殺死。因此,就要使用多執行緒,將一些複雜的耗時操作移動到其他的執行緒中去執行,提高程式的執行效率。

子執行緒的建立

Android在一開始就會自動建立一個主執行緒。Android和Java一樣,可以使用Thread類來開闢一個新的執行緒。

new Thread(new Runnable() {
            @Override
            public void run() {
            //耗時操作  
            }
        }).start();

主執行緒與子執行緒的通訊方式

  • Handler+Thread方式
    以前的學習中, 有關於Handler的詳細解釋;
    http://blog.csdn.net/bistusim/article/details/52152454
    handler傳送Message訊息,然後在主執行緒中的handler的回撥方法中接受並處理訊息。
  • runOnUiThread更新主執行緒
    Activity.runOnUiThread(Runnable);這是一個Activity的一個方法。把需要更新的UI程式碼建立在Runnable中。
 runOnUiThread(new Runnable() {
     @Override
     public void run() {
     //更新UI操作
     }
 });
 //原始碼
 public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else
{ action.run(); } }
  • View.post(Runnable)更新主執行緒
textview.post(new Runnable() {
                            @Override
                            public void run() {
//更新UI                            }
                        });
//原始碼
public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }
        // Assume that post will succeed later
        ViewRootImpl.getRunQueue().post(action);
        return true;
    }
 //通過原始碼可以看出,以上兩種方法實質上都是獲得了UI執行緒的Handler,然後使用post(Runnable)進行相關的更新操作。
  • AsyncTask
    AsyncTask是Google提供的一個封裝過的後臺任務類,適用於簡單的非同步處理。
    使用時需要繼承AsyncTask類,並且至少要重寫兩個方法;
    • doInBackground(Params…) 後臺執行,比較耗時的操作都可以放在這裡。注意這裡不能直接操作UI。此方法在後臺執行緒執行,完成任務的主要工作,通常需要較長的時間。
    • onPostExecute(Result) 相當於Handler 處理UI的方式,在這裡面可以使用在doInBackground 得到的結果處理操作UI。 此方法在主執行緒執行,任務執行的結果作為此方法的引數返回。

除了上面的兩個必須重寫的方法外,還有onPreExecute()方法,當任務執行之前開始呼叫此方法。
AsyncTask定義了三種泛型型別 Params,Progress和Result。
- Params 啟動任務執行的輸入引數,比如HTTP請求的URL,或者String,Integer等。
- Progress 後臺任務執行的百分比。
- Result 後臺執行任務最終返回的結果,比如String。會傳遞給onPostExecute()方法。

執行緒安全

如果程式碼所在的程序中有多個子執行緒在同時執行,而這些子執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全。

老師還提到一個比較特別的方法,ProgressBar.setProgress()可以在子執行緒中直接使用,這看似違背了不能在子執行緒中進行更新UI的操作,但是看了原始碼發現,它實際還是獲得了當前的UI執行緒進行更新UI操作。