1. 程式人生 > >Android的多執行緒

Android的多執行緒

今天來總結一下Android的多執行緒,分別介紹一下四種方法。『原理都是:子執行緒發訊息到主執行緒進行更新UI』

    1.Activity.runOnUiThread(Runnable)
    2.View.post(Runnable),View.postDelay(Runnable,long)
    3.Handler
    4.AsyncTask

----------------------------------------------------------------------------------------------------------------

    1.Activity.runOnUiThread(Runnable)

利用Activity.runOnUiThread(Runnable)把更新ui的程式碼建立在Runnable中,然後在需要更新ui時,把這個Runnable物件傳給Activity.runOnUiThread(Runnable)。 Runnable對像就能在ui程式中被呼叫。如果當前執行緒是UI執行緒,那麼行動是立即執行。如果當前執行緒不是UI執行緒,操作是釋出到事件佇列的UI執行緒。

public class TestActivity extends Activity {
    Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.handler_msg);
        btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // 模擬耗時的操作。
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 更新主執行緒UI
                        TestActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                btn.setText("更新完畢!");
                            }
                        });
                    }
                }).start();
            }
        });
    }
}


2.1View.post(Runnable)


mTextView.post(new Runnable() {
    @Override
    public void run() {
        mTextView.setText("yes, 獲取到資料了!#");
        mTextView.setBackgroundColor(Color.BLUE);
    }
});
2.2 View.postDelay(Runnable,long)

Android View 都有一個postDelayed(Runnable,毫秒數),用於延遲UI操作的方法,下面的程式碼中就是300毫秒之後,calendar_view才顯示

private void method() {
    blur_view.setBackgroundColor(Color.BLACK);
    blur_view.postDelayed(new Runnable() {
        public void run() {
            calendar_view.setVisibility(View.GONE);
            CalendarActivity.this.finish();
        }
    }, 300);
}

5秒鐘倒計時

        num = (TextView) findViewById(R.id.num);
        num.postDelayed(new Runnable() {
            @Override
            public void run() {
                num.setText("" + index);
                index--;
                if (index == 0) {
                    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                    startActivity(intent);
                } else {
                    num.postDelayed(this, 1000);
                }
            }
        }, 1000);

3.Handler的機制

Android的主執行緒叫UI執行緒,從名字可知主執行緒主要是用來建立,更新UI的。所以耗時操eg:網路訪問,檔案處理,多媒體處理,等都需要在子執行緒中完成。(為了保證UI流暢度嘛)此時就需要Handler。充當子執行緒與主執行緒之間的橋樑。

 通常將handler宣告在Activity中,然後覆寫Handler 中的handleMessage方法,當子執行緒呼叫handler.sendMessage()方法後,handleMessage方法將會在主執行緒中執行。

Handler,Message,Looper,MessageQueue等物件的關係。

主執行緒中Android預設呼叫Looper.prepare()方法。呼叫的目的是:在Looper中建立MessageQueue成員變數,並把Looper物件繫結到當前執行緒中。當子執行緒呼叫Handler的sendMessage(物件)方法時候,就將Message物件新增到Looper建立的MessageQueue佇列中,同時給Message指定了Handler物件。主執行緒預設執行了Looper.looper() 方法,該方法從Looper的成員變數MessageQueue中取出Message,然後呼叫Message的handler物件的handleMessage()方法。這樣就完成了整個訊息機制。

4.AsyncTask.

AsyncTask是種輕量級的非同步任務類。

官方API翻譯:

AsyncTask使適當的和易用的UI執行緒。這個類可以執行後臺操作,並在使用者介面上釋出結果,而不必處理執行緒/或處理程式。

AsyncTask的設計是圍繞執行緒和處理器的一個輔助類,並不構成一個通用的執行緒框架。asynctasks應該用於短作業(最多。幾秒鐘)如果你需要保持執行緒執行很長一段時間,我們強烈建議您使用不同的java.util.concurrent包如執行API提供的,執行緒池和futuretask。

非同步任務被定義為一個在後臺執行緒上執行的運算,其結果是在使用者介面上釋出的。一個非同步任務是由3的泛型型別定義為引數,過程和結果,和4個步驟,稱為onpreexecute,doInBackground,onProgressUpdate和onpostexecute。

AsyncTask必須被子類繼承使用。子類至少重寫一個方法(doInBackground(Params...)),最經常會重寫第二個方法(onPostExecute(result))

使用案例:


呼叫方式


AsyncTask的泛型

一個非同步任務使用的三種類型如下:

1.Params,the type of the parameters sent to the task upon execution.(在執行時傳送到任務的引數型別

2.Progress,the type of the progress units published during the background computation.(後臺計算過程中的進度單元的型別。)

3.Result,the type of the result of the background computation.(後臺執行的結果型別。)

(不是所有的引數都需要,不用時可以返回void型別)

onPreExecute     執行順序的第一個。可以進行一些初始化操作(執行在主執行緒中)!

doInBackground  執行一些耗時操作,將結果資料返回(執行在子執行緒中)!

onPostExecute    顯示結果資料更新UI(執行在主執行緒中)!

task.execute(引數) 呼叫的方法在主執行緒中!

Note:

1.由於Handler需要和主執行緒互動,而Handler又是內置於AsyncTask中,所以AsyncTask的建立必須在主執行緒。

2.AsyncTaskResult的doInBackground(Params)方法執行非同步任務執行在子執行緒中,其他方法執行在主執行緒中,可以操作UI元件。

3.不要手動的去呼叫AsyncTask的onPreExecute, doInBackground, publishProgress, onProgressUpdate, onPostExecute方法,這些都是由android系統自動呼叫的。

4.一個AsyncTask任務只能被執行一次。

5.執行中可以隨時呼叫cancel(boolean)方法取消任務,如果成功呼叫isCancel()會返回true,並不會執行onPostExecute(),取而代之的是呼叫onCancelled()。從原始碼看,如果這個任務已經執行了這個時候呼叫cancel是不會真正的把task結束,而是繼續執行,只不過改變的是執行之後的回撥方法的onPostExecute還是onCancelled.