天天看點

android AsyncTask介紹

asynctask和handler對比

1 ) asynctask實作的原理,和适用的優缺點

asynctask,是android提供的輕量級的異步類,可以直接繼承asynctask,在類中實作異步操作,并提供接口回報目前異步執行的程度(可以通過接口實作ui進度更新),最後回報執行的結果給ui主線程.

使用的優點:

l  簡單,快捷

l  過程可控

使用的缺點:

l  在使用多個異步操作和并需要進行ui變更時,就變得複雜起來.

2 )handler異步實作的原理和适用的優缺點

在handler 異步實作時,涉及到 handler, looper, message,thread四個對象,實作異步的流程是主線程啟動thread(子線程)àthread(子線程)運作并生成message-àlooper擷取message并傳遞給handleràhandler逐個擷取looper中的message,并進行ui變更。

使用的優點:

l  結構清晰,功能定義明确

l  對于多個背景任務時,簡單,清晰

使用的缺點:

l  在單個背景異步處理時,顯得代碼過多,結構過于複雜(相對性)

asynctask介紹

android的asynctask比handler更輕量級一些,适用于簡單的異步處理。

首先明确android之是以有handler和asynctask,都是為了不阻塞主線程(ui線程),且ui的更新隻能在主線程中完成,是以異步處理是不可避免的。

android為了降低這個開發難度,提供了asynctask。asynctask就是一個封裝過的背景任務類,顧名思義就是異步任務。

asynctask直接繼承于object類,位置為android.os.asynctask。要使用asynctask工作我們要提供三個泛型參數,并重載幾個方法(至少重載一個)。

asynctask定義了三種泛型類型 params,progress和result。

params 啟動任務執行的輸入參數,比如http請求的url。

progress 背景任務執行的百分比。

result 背景執行任務最終傳回的結果,比如string。

使用過asynctask 的同學都知道一個異步加載資料最少要重寫以下這兩個方法:

doinbackground(params…) 背景執行,比較耗時的操作都可以放在這裡。注意這裡不能直接操作ui。此方法在背景線程執行,完成任務的主要工作,通常需要較長的時間。在執行過程中可以調用publicprogress(progress…)來更新任務的進度。

onpostexecute(result)  相當于handler 處理ui的方式,在這裡面可以使用在doinbackground 得到的結果處理操作ui。 此方法在主線程執行,任務執行的結果作為此方法的參數傳回

有必要的話你還得重寫以下這三個方法,但不是必須的:

onprogressupdate(progress…)   可以使用進度條增加使用者體驗度。 此方法在主線程執行,用于顯示任務執行的進度。

onpreexecute()        這裡是最終使用者調用excute時的接口,當任務執行之前開始調用此方法,可以在這裡顯示進度對話框。

oncancelled()             使用者調用取消時,要做的操作

使用asynctask類,以下是幾條必須遵守的準則:

task的執行個體必須在ui thread中建立;

execute方法必須在ui thread中調用;

不要手動的調用onpreexecute(), onpostexecute(result),doinbackground(params...), onprogressupdate(progress...)這幾個方法;

該task隻能被執行一次,否則多次調用時将會出現異常;

一個超簡單的了解 asynctask 的例子:

main.xml

[java] view plaincopy

<?xml version="1.0" encoding="utf-8"?>  

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"  

    android:orientation="vertical"  

    android:layout_width="fill_parent"  

    android:layout_height="fill_parent"  

    >  

    <textview    

    android:id="@+id/textview01"  

    android:layout_width="fill_parent"   

    android:layout_height="wrap_content"   

    />  

   <progressbar   

   android:id="@+id/progressbar02"  

    style="?android:attr/progressbarstylehorizontal"   

    <button  

    android:id="@+id/button03"  

    android:text="更新progressbar"  

</linearlayout>  

mainactivity.java

[html] view plaincopy

package vic.wong.main;  

import android.app.activity;  

import android.os.bundle;  

import android.view.view;  

import android.view.view.onclicklistener;  

import android.widget.button;  

import android.widget.progressbar;  

import android.widget.textview;  

public class mainactivity extends activity {  

    private button button;  

    private progressbar progressbar;  

    private textview textview;  

    @override  

    public void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.main);  

        button = (button)findviewbyid(r.id.button03);  

        progressbar = (progressbar)findviewbyid(r.id.progressbar02);  

        textview = (textview)findviewbyid(r.id.textview01);  

        button.setonclicklistener(new onclicklistener() {  

            @override  

            public void onclick(view v) {  

                progressbarasynctask asynctask = new progressbarasynctask(textview, progressbar);  

                asynctask.execute(1000);  

            }  

        });  

    }  

}  

netoperator.java

//模拟網絡環境  

public class netoperator {  

    public void operator(){  

        try {  

            //休眠1秒  

            thread.sleep(1000);  

        } catch (interruptedexception e) {  

            // todo auto-generated catch block  

            e.printstacktrace();  

        }  

progressbarasynctask .java 

import android.os.asynctask;  

/**  

 * 生成該類的對象,并調用execute方法之後  

 * 首先執行的是onproexecute方法  

 * 其次執行doinbackgroup方法  

 *  

 */  

public class progressbarasynctask extends asynctask<integer, integer, string> {  

    public progressbarasynctask(textview textview, progressbar progressbar) {  

        super();  

        this.textview = textview;  

        this.progressbar = progressbar;  

    /**  

     * 這裡的integer參數對應asynctask中的第一個參數   

     * 這裡的string傳回值對應asynctask的第三個參數  

     * 該方法并不運作在ui線程當中,主要用于異步操作,所有在該方法中不能對ui當中的空間進行設定和修改  

     * 但是可以調用publishprogress方法觸發onprogressupdate對ui進行操作  

     */  

    protected string doinbackground(integer... params) {  

        netoperator netoperator = new netoperator();  

        int i = 0;  

        for (i = 10; i <= 100; i+=10) {  

            netoperator.operator();  

            publishprogress(i);  

        return i + params[0].intvalue() + "";  

     * 這裡的string參數對應asynctask中的第三個參數(也就是接收doinbackground的傳回值)  

     * 在doinbackground方法執行結束之後在運作,并且運作在ui線程當中 可以對ui空間進行設定  

    protected void onpostexecute(string result) {  

        textview.settext("異步操作執行結束" + result);  

    //該方法運作在ui線程當中,并且運作在ui線程當中 可以對ui空間進行設定  

    protected void onpreexecute() {  

        textview.settext("開始執行異步線程");  

     * 這裡的intege參數對應asynctask中的第二個參數  

     * 在doinbackground方法當中,,每次調用publishprogress方法都會觸發onprogressupdate執行  

     * onprogressupdate是在ui線程中執行,所有可以對ui空間進行操作  

    protected void onprogressupdate(integer... values) {  

        int vlaue = values[0];  

        progressbar.setprogress(vlaue);  

}  

繼續閱讀