methods asynctask教學 - Android:我如何傳遞參數給AsyncTask的onPreExecute()?




asynctask用法 cancel (5)

我使用AsyncTask來加載作為內部類實現的操作。

onPreExecute()我顯示一個加載對話框,然後我再次隱藏onPostExecute() 。 但對於我事先知道的一些加載操作,他們會很快完成,因此我不想顯示加載對話框。

我想通過一個布爾參數來指示,我可以傳遞給onPreExecute()但顯然由於某種原因onPreExecute()不帶任何參數。

明顯的解決方法可能是在我的AsyncTask或外部類中創建一個成員字段,在每次加載操作之前我都必須設置該成員字段,但這看起來不太優雅。 有一個更好的方法嗎?


Answers

為什麼,如何以及將哪些參數傳遞給Asynctask <>,請參閱here詳細here 。 我認為這是最好的解釋。

Google的Android文檔說明:

異步任務由3個泛型類型定義,稱為Params,Progress和Result,以及4個步驟,分別稱為onPreExecute,doInBackground,onProgressUpdate和onPostExecute。

AsyncTask的泛型類型:

異步任務使用的三種類型如下:

參數,執行時發送給任務的參數的類型。 進度,在後台計算期間發布的進度單位的類型。 結果,後台計算結果的類型。 並非所有類型總是由異步任務使用。 要將某個類型標記為未使用,只需使用類型Void:

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }

您可以進一步參考: http://developer.android.com/reference/android/os/AsyncTask.html : http://developer.android.com/reference/android/os/AsyncTask.html

或者你可以通過引用Sankar-Ganesh的博客來明確AsyncTask的作用

那麼典型的AsyncTask類的結構如下所示:

private class MyTask extends AsyncTask<X, Y, Z>

    protected void onPreExecute(){ 

    } 

此方法在啟動新線程之前執行。 沒有輸入/輸出值,所以只需初始化變量或任何你認為你需要做的事情。

protected Z doInBackground(X...x){

}

AsyncTask類中最重要的方法。 你必須在這裡把所有你想做的事情放在後台,在與主要的線程不同的線程中。 在這裡,我們有一個類型為“X”的對像數組作為輸入值(您在頭文件中看到了什麼?我們有“...擴展AsyncTask”這些是輸入參數的類型)並返回類型的對象“Z”。

保護無效onProgressUpdate(Y Y){

}使用publishProgress(y)方法調用此方法,通常在您想要在主屏幕中顯示任何進度或信息時使用此方法,例如顯示您在後台執行的操作進度的進度條。

保護無效onPostExecute(Z Z){

}在後台操作完成後調用此方法。 作為輸入參數,您將收到doInBackground方法的輸出參數。

那麼X,Y和Z類型呢?

正如你可以從上述結構中推斷出的那樣:

X – The type of the input variables value you want to set to the background process. This can be an array of objects.

 Y – The type of the objects you are going to enter in the onProgressUpdate method.

 Z – The type of the result from the operations you have done in the background process.

我們如何從外部課堂調用這個任務? 只需以下兩行:

MyTask myTask = new MyTask();

myTask.execute(x);

其中x是類型X的輸入參數。

一旦我們的任務運行,我們就可以從“外部”中找到它的狀態。 使用“getStatus()”方法。

myTask.getStatus(); 我們可以收到以下狀態:

RUNNING - 表示任務正在運行。

PENDING - 表示該任務尚未執行。

完成 - 表示onPostExecute(Z)已完成。

關於使用AsyncTask的提示

不要手動調用PreExecute,doInBackground和onPostExecute方法。 這是由系統自動完成的。

您不能在另一個AsyncTask或Thread內調用AsyncTask。 方法執行的調用必須在UI線程中完成。

onPostExecute方法在UI線程中執行(在這裡你可以調用另一個AsyncTask!)。

任務的輸入參數可以是一個Object數組,這樣你可以放置任何你想要的對象和類型。


你可以重寫構造函數。 就像是:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    public MyAsyncTask(boolean showLoading) {
        super();
        // do stuff
    }

    // doInBackground() et al.
}

然後,在調用任務時,請執行以下操作:

new MyAsyncTask(true).execute(maybe_other_params);

編輯:這比創建成員變量更有用,因為它簡化了任務調用。 比較上面的代碼與:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();

1)對我來說,將參數傳遞給異步任務的最簡單方法就是這樣

// To call the async task do it like this
Boolean[] myTaskParams = { true, true, true };
myAsyncTask = new myAsyncTask ().execute(myTaskParams);

聲明並使用像這樣的異步任務

private class myAsyncTask extends AsyncTask<Boolean, Void, Void> {

    @Override
    protected Void doInBackground(Boolean...pParams) 
    {
        Boolean param1, param2, param3;

        //

          param1=pParams[0];    
          param2=pParams[1];
          param3=pParams[2];    
      ....
}                           

2)將方法傳遞給異步任務為了避免多次編寫異步任務基礎結構(線程,messagenhandler,...),您可能會考慮將應該在異步任務中執行的方法作為參數傳遞。 以下示例概述了這種方法。 此外,您可能需要繼承異步任務以在構造函數中傳遞初始化參數。

 /* Generic Async Task    */
interface MyGenericMethod {
    int execute(String param);
}

protected class testtask extends AsyncTask<MyGenericMethod, Void, Void>
{
    public String mParam;                           // member variable to parameterize the function
    @Override
    protected Void doInBackground(MyGenericMethod... params) {
        //  do something here
        params[0].execute("Myparameter");
        return null;
    }       
}

// to start the asynctask do something like that
public void startAsyncTask()
{
    // 
    AsyncTask<MyGenericMethod, Void, Void>  mytest = new testtask().execute(new MyGenericMethod() {
        public int execute(String param) {
            //body
            return 1;
        }
    });     
}

您可以在任務構造函數中傳遞參數,或者在調用execute時:

AsyncTask<Object, Void, MyTaskResult>

第一個參數(Object)在doInBackground中傳遞。 第三個參數(MyTaskResult)由doInBackground返回。 您可以將它們更改為所需的類型。 三個點意味著可以傳遞零個或多個對象(或它們的一個數組)作為參數。

public class MyActivity extends AppCompatActivity {

    TextView textView1;
    TextView textView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);    
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);

        String input1 = "test";
        boolean input2 = true;
        int input3 = 100;
        long input4 = 100000000;

        new MyTask(input3, input4).execute(input1, input2);
    }

    private class MyTaskResult {
        String text1;
        String text2;
    }

    private class MyTask extends AsyncTask<Object, Void, MyTaskResult> {
        private String val1;
        private boolean val2;
        private int val3;
        private long val4;


        public MyTask(int in3, long in4) {
            this.val3 = in3;
            this.val4 = in4;

            // Do something ...
        }

        protected void onPreExecute() {
            // Do something ...
        }

        @Override
        protected MyTaskResult doInBackground(Object... params) {
            MyTaskResult res = new MyTaskResult();
            val1 = (String) params[0];
            val2 = (boolean) params[1];

            //Do some lengthy operation    
            res.text1 = RunProc1(val1);
            res.text2 = RunProc2(val2);

            return res;
        }

        @Override
        protected void onPostExecute(MyTaskResult res) {
            textView1.setText(res.text1);
            textView2.setText(res.text2);

        }
    }

}

最簡單的方式(這是令人驚訝的僅在評論中提到,因此我發佈為答案)是:

textview.setGravity(Gravity.CENTER)






android methods parameters android-asynctask