1. 程式人生 > >第一行程式碼 學習筆記 後臺的默默勞動者--探究服務

第一行程式碼 學習筆記 後臺的默默勞動者--探究服務

10.1 服務是什麼


10.2 Android多執行緒程式設計

定義執行緒:新建一個類繼承自Thread,然後重寫父類的run()方法,如下所示:

class MyThread extends Thread{

      public void run(){

        //處理具體的邏輯

      }

}

啟動執行緒:如下所示

new MyThread().start();

當然,使用繼承的方式耦合性有點高,更多的時候是使用Runnalbe介面方法來定義一個執行緒,如下所示:

class MyThread implement Runnable{

      public void run(){

        //處理具體的邏輯

      }

}

如果使用了這種方法,啟動執行緒的方法也需要進行相應的改變,如圖所示:

MyThread myThread=new MyThread();

new Thread(myThread).start();

當然,如果你不想專門再定義一個類去實現Runnable介面,也可以使用匿名類的方式,如下所示

new Thread(new Runnable(){

    public void run(){

        //處理具體的邏輯

    }

}).start();

10.2.2 在子執行緒中跟新UI


點選後程序崩潰 原因:Android不允許在子執行緒中進行UI操作。

但是有些時候,我們必須在子執行緒裡執行一些耗時任務,然後根據任務執行的結果來跟新相應的UI控制元件。

對於這種情況,Android提供了一套非同步訊息處理機制,完美地解決了在子執行緒中進行UI操作地問題

10.2.3 解析非同步訊息處理機制

1.Message

 message是線上程之間傳遞地訊息,它可以在內部攜帶少量地資訊,用於在不同執行緒之間交換資料。可以使用Message的what()欄位,還可以使用arg1和arg2欄位來攜帶一些整形資料,使用obj欄位攜帶一個Object物件

2.Handler

 Handler主要用於傳送和處理訊息,傳送訊息一般是使用Handler的sendMessage()方法,而發出的訊息經過一系列地輾轉處理後,最終會傳遞到Handler的handleMessage()方法中。

3.MessageQueue

 MessageQueue是訊息佇列的意思,它主要用於存放所有通過Handler傳送的訊息,這部分訊息會一直存在於訊息佇列中,等待被處理。每個執行緒都只會有一個MessageQueue物件。

4.Looper

 Looper是每個執行緒中的MessageQueue的管家。呼叫Looper的loop()方法後,就會進入到一個無限迴圈當中然後每當發現MessageQueue中存在一條訊息,就會將它取出,並傳遞到Handler的handleMessage()方法中,每個執行緒都只會有一個Looper物件



10.2.4 使用AsyncTask

  

  AsyncTask的基本用法,由於AsyncTask是一個抽象類,所以如果我們想使用它,就必須建立一個子類去繼承它。在繼承時我們可以為AsyncTask類指定三個泛型引數,這3個引數的用途如下。

Params:在執行AsyncTask時需要傳入的引數,可用於後臺任務中使用。

Progress:後臺執行任務時,如果需要在介面上顯示當前的進度,則使用這裡指定的泛型作為進度單位。

Result:當任務執行完畢後,如果需要對結果進行返回,則使用這裡指定的泛型作為返回值型別

因此,一個最簡單的自定義AsyncTask就可以寫成如下方式



1.onPreExecute()  這個方法會在後臺任務開始之前呼叫,用於進行一些介面上的初始化操作,比如顯示一個進度對話方塊條等

2.doInBackground(Params....)  這個方法中的所有程式碼都會在子執行緒中執行,我們應該在這裡去處理所有的耗時任務。任務一旦完成就可以通過return語句來將任務的執行結果返回,如果AsyncTask的第三個泛型引數指定時Void,就不可以返回任務執行的結果。注意,在這個方法中時不可以進行UI操作的,如果需要跟新UI元素,比如反饋當前任務的執行進度,可以呼叫publish Progress(Progress...)方法來完成。

3.onProgressUpdate(Progress...)  當後臺任務中呼叫了 publish Progress(Progress...)方法後onProgressUpdate(Progress...) 方法就會很快被呼叫,該方法中攜帶的引數就是在後臺任務中傳遞過來的。在這個方法中可以對UI進行操作,利用引數中的數值就可以對介面元素進行相應的跟新

4.onPostExecute(Result) 當後臺任務執行完畢並通過return語句進行返回時,這個方法就會很快被呼叫,返回的資料就會作為引數傳遞到此方法中,可以利用返回的資料進行UI操作。

簡單來說,使用AsyncTask的訣竅就是,在doInBackground(Params....) 方法中執行具體的耗時任務,在onProgressUpdate(Progress...)方法中進行UI操作,在onPostExecute(Result)方法中執行一些任務的收尾工作。

想要啟動這個任務,只需要編寫以下程式碼:

new DownloadTask().execute();

10.3 服務的基本用法

10.3.1 定義一個服務





10.3.2 啟動和停止服務



10.3.3 活動和服務進行通訊



10.4 服務的什麼週期


10.5 服務的更多技巧

10.5.1 使用前臺服務



10.5.2 使用IntentService



10.6 服務的最佳實踐--完整版的下載例項