第一行程式碼 學習筆記 後臺的默默勞動者--探究服務
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 服務的最佳實踐--完整版的下載例項