AsyncTask使用筆記

文/大大大大峰哥

AsyncTask是基于異步消息處理機制,只是Android為了方便我們使用,將它封裝了起來,這讓我們可以更加簡單便捷的使用,可以輕松地從子線程切換到主線程。如果想簡單了解異步消息處理機制可以看我另外一篇博文簡單描述Android異步原理。

使用

AsyncTask是一個抽象類,使用它需要繼承它,繼承的時候需要注意它擁有三個泛型參數:Params,Progress,Result。

Params:需要傳入的參數,用于后臺任務中使用,如果你不需要傳入數據可以將該設置為Void。

Progress:后臺任務執行時,往往需要了解后臺任務的進度,這個參數自行設定成為你需要反映進度的數據類型,比如我需要將進度用Integer返回等等。

Result:當任務執行完畢后,則使用該類型作為反饋類型,比如使用Boolean類型,那么你可以返回true告訴主線程,我成功運行。

方法

在我們繼承AsyncTask后,我們需要了解幾個重用的重寫方法。

onPreExecute():在我們使用AsyncTask需要初始化操作的時候,我們可以重寫該方法并在里面初始數據以及UI。比如我們可以初始化一個下載進度條。

doInBackground(Params ...):這個是當你繼承AsyncTask必須重寫的方法,該方法所有代碼均在子線程中運行,一般是用來處理耗時操作。比如我們在這方法向網絡獲取數據。

注意:因為在子線程中運行,那么就不能做更新UI的操作。

onProgressUpdate(Progress ...):在該類中調用publishProgress方法后,才會運行這個方法中的代碼,通過傳入的Progress類型后我們可以處理并更新UI。

onPostExecute(Result ):當我們后臺任務(doInBackground)執行完畢之后,return 傳遞的值進入onPostExecute方法中,向我們傳遞任務執行結果,比如我們可以關閉下載進度條對話框,并且提示下載成功或者失敗。

代碼

學習AsyncTask光靠理論說是不行的,所以需要看代碼來輔助理解,在看完之后自己敲一遍才是自己的東西,下面是做了一個模擬下載的功能。

(一)MainActivity.java

package com.example.deme2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButton= (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new MyAsyncTask(MainActivity.this).execute();
            }
        });


    }
}

(二)MyAsyncTask.java

package com.example.deme2;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import static android.content.ContentValues.TAG;

/**
 * Created by TangZhiFeng on 2016/12/14.
 */

public class MyAsyncTask extends AsyncTask<Void, Integer
        , Boolean> {


    Context mContext;
    AlertDialog mAlertDialog;
    int mDownProgress;

    public MyAsyncTask(Context context) {
        mContext = context;
    }

    /*
        * 這個函數一般是完成一些初始化操作。
        * */
    @Override
    protected void onPreExecute() {
        mDownProgress = 0;
        mAlertDialog = new AlertDialog.Builder(mContext)
                .setTitle("下載進度")
                .setMessage(mDownProgress + "")
                .create();
        mAlertDialog.show();
    }


    /*
    * 這個函數一般都是處理一些耗時操作,同時這個函數
    * 是在子線程完成,不能進行UI更新操作
    * */
    @Override
    protected Boolean doInBackground(Void... params) {

        try {
            while (true) {
                mDownProgress = doDownload();//模擬下載過程
                if (mDownProgress > 100) {
                    break;
                }
                Thread.sleep(1000);
                publishProgress(mDownProgress);
                Log.i(TAG, "doInBackground: "+mDownProgress);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    private int doDownload() {
        return mDownProgress+5;
    }

    /*
    * 調用publishProgress后,進入這個函數,可以進
    * 行UI操作
    * */
    @Override
    protected void onProgressUpdate(Integer... values) {
        mAlertDialog.setMessage("" + values[0]);
    }

    /*
    * 在后臺任務執行完畢后調用該函數
    * */
    @Override
    protected void onPostExecute(Boolean aBoolean) {
        mAlertDialog.dismiss();//關閉對話框
        if (aBoolean) {
            Toast.makeText(mContext, "下載完成", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(mContext, "下載失敗", Toast.LENGTH_SHORT).show();
        }
    }
}

總結

MyAsyncTask流程圖

End

希望大家多多指點,有問題指出來,互相幫助互相學習。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容