天天看點

AsyncTask與IntentService

摘自:https://blog.csdn.net/qq_35572068/article/details/84961265

摘自:https://blog.csdn.net/lxg1234567890/article/details/27048949

Android主線程,也就是UI線程,其最大用途在于運作四大元件以及處理他們和使用者的互動。其他耗時操作交給子線程,如網絡請求、I/O操作,從Android3.0開始,網絡通路必須在子線程中進行,否則将會失敗并抛棄異常,避免ANR現象。

AsyncTask是輕量級異步任務類,封裝了Thread和Handler。

AsyncTask:

onPreExecute(),異步執行之前,此方法被調用做一些準備工作。doInBackground()線上程池中執行,此方法用于執行異步任務。doInBackground()線上程池中執行,此方法用于執行異步任務,執行過程中可以調用publishProgress()方法更新任務執行進度。onProgressUpdate()方法在主線程中執行,每次任務進度更新時被調用。onPostExecute()在任務執行完成時被調用,其參數為doInBackground()的傳回參數。

執行順序與聯系如下圖

AsyncTask與IntentService

代碼Demo:

public class DownloadFileAsyncTackDemo extends AsyncTask<URL, Integer, Long> {
 
    protected  Long doInBackground(URL... urls){
        int count = urls.length;
        long totalSize = 0;
        for(int i = 0; i < count; i++){
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) (i / (float) count) * 100 );
            if(isCancelled()){
                break;
            }
        }
        return totalSize;
    }
 
    protected void onProgressUpdate(Integer... progress){
        setProgressPercent(progress[0]);
    }
 
    protected void onPostExecute(Long result){
        Log.d("",String.valueOf(result));
    }
 
}
           

AsyncTask注意事項:

  1. 必須在主線程中加載,意味着第一次通路AsyncTask必須發生在主線程。
  2. Execute方法必須在UI線程調用。不能直接調用onPreExecute()、doInBackground()、publishProgress()、onPostExecute()、onProgressUpdate()方法。
  3. 一個AsyncTask對象隻能被執行一次,既隻調用一次。
  4. AsyncTask在4.1.1上是串行的,在2.3.3上是并行的。在3.0版本後可使用executeOnExecutor()方法啟動以實作并行。

IntentService:

         IntentService是一種特殊的Service繼承自Service,任務執行後會自動停止。因為其是Service,是以優先級會比單純的線程高。且不容易被系統殺死。第一次啟動調用onCreate,每次啟動調用一次onStartCommand,在onStartCommd處理每個背景任務的Intent。

OnHandleIntent():抽象類,每次都需要實作。是處理任務的地方

每執行一個背景任務,必須啟動一次Intentservice。當有多個背景任務,按照外界發起的順序執行。

示例:

public class MyService extends IntentService {

    private static final String TAG = MyService.class.getSimpleName();

    private int count = 0;

    public MyService() {
        super(TAG);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // TODO Auto-generated method stub
        //在這裡添加我們要執行的代碼,Intent中可以儲存我們所需的資料,
        //每一次通過Intent發送的指令将被順序執行
        count ++;
        Log.w(TAG, "count::" + count);
    }
}
           

在外部元件中開啟服務:在這裡我們在Activity中利用Intent循環10次開啟服務。

for (int i = 0; i < 10; i++) {
        Intent intent = new Intent(MainActivity.this, MyService.class);
        startService(intent);
}
           

結果:

AsyncTask與IntentService

IntentService和AsyncTask有啥不同?

總結出一句話:IntentService 是Serivce+handler的結合産物 AsyncTask是thread+handler的結合産物。

為什麼用service而不用thread:

1.我們先拿 Thread 來說 ,Thread 的運作是獨立于 Activity 的,也就是說當一個 Activity 被 finish 之後 ,如果你沒有主動停止 Thread 或者 Thread 裡的 run 方法沒有執行完畢的話,Thread 也會一直執行。是以這裡會出現一個問題:當 Activity 被 finish 之後,你不再持有該 Thread 的引用。另一方面,你沒有辦法在不同的 Activity 中對同一 Thread 進行控制。

2.1 location serivce 不是一個單獨的程序,它和應用程式在同一個程序中。隻能在目前應用中調用service。kill目前應用則service也随之消亡。

2.2 remote service 獨立與應用程式之外程序的程序(必須在聲明的時候以android:process=":remote"方式聲明),配合AIDL可以實作程序間的互相調用。remote service所依附的那個應用如果應用kill掉,但是remoteservice還在運作,除非你解除安裝目前應用。

IntentService 是Serivce+handler的結合産物,可以在onHandleIntent直接處理耗時操作。而本地service和遠端service不能在onStart方法中執行耗時操作,隻能放在子線程中進行處理,當有新的intent請求過來都會線onStartCommond将其入隊列,當第一個耗時操作結束後,就會處理下一個耗時操作(此時調用onHandleIntent),都執行完了自動執行onDestory銷毀IntengService服務。

AsyncTask是thread+handler的結合産物,減少程式中線程過多開銷過大,操作和管理更加友善。AsyncTask執行個體必須在UI Thread中建立,execute方法必須在UI Thread中調用不能手動調用onPreExcute(),onPostExcute(Result)。task隻能被執行一次,否則将出現異常。