Android:如何将参数传递给AsyncTask的onPreExecute()?

Ste*_*los 113 parameters methods android android-asynctask

我使用一个AsyncTask加载操作,我实现为内部类.

onPreExecute()我显示一个加载对话框,然后我再次隐藏onPostExecute().但对于我提前知道的一些加载操作,它们会很快完成,因此我不想显示加载对话框.

我想通过一个布尔参数来表明这个,我可以传递给它,onPreExecute()但显然由于某种原因onPreExecute()不采取任何参数.

显而易见的解决方法可能是在我的AsyncTask或外部类中创建一个成员字段,我必须在每次加载操作之前设置它,但这似乎不是很优雅.有一个更好的方法吗?

Fel*_*lix 228

您可以覆盖构造函数.就像是:

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

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

    // doInBackground() et al.
}
Run Code Online (Sandbox Code Playgroud)

然后,在调用任务时,执行以下操作:

new MyAsyncTask(true).execute(maybe_other_params);
Run Code Online (Sandbox Code Playgroud)

编辑:这比创建成员变量更有用,因为它简化了任务调用.比较上面的代码:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Run Code Online (Sandbox Code Playgroud)

  • 这正是我现在所做的.我仍然需要一个成员变量,但是在AsyncTask而不是外部类中,如果这就是你的意思.这就是我所做的:私有类MyAsyncTask扩展AsyncTask <Void,Void,Void> {private boolean showLoading; public MyAsyncTask(boolean showLoading){super(); this.showLoading = showLoading; // do stuff} protected void onPreExecute(){if(showLoading){// ...}} // doInBackground()et al.} (3认同)

Kar*_*arl 60

1)对我而言,将参数传递给异步任务的最简单方法就是这样

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

像这里声明并使用异步任务

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];    
      ....
}                           
Run Code Online (Sandbox Code Playgroud)

2)将方法传递给async-task 为了避免多次编写async-Task基础结构(thread,messagenhandler,...),您可能会考虑将应该在async-task中执行的方法作为参数传递.以下示例概述了这种方法.此外,您可能需要将async-task子类化为在构造函数中传递初始化参数.

 /* 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;
        }
    });     
}
Run Code Online (Sandbox Code Playgroud)


Nav*_*ali 10

为什么,如何以及将哪些参数传递给Asynctask <>,请参见此处的详细信息.我认为这是最好的解释.

谷歌的Android文档说:

异步任务由3种泛型类型定义,称为Params,Progress和Result,以及4个步骤,称为onPreExecute,doInBackground,onProgressUpdate和onPostExecute.

AsyncTask的泛型类型:

异步任务使用的三种类型如下:

Params,执行时发送给任务的参数类型.进度,后台计算期间发布的进度单元的类型.结果,后台计算结果的类型.并非所有类型都始终由异步任务使用.要将类型标记为未使用,只需使用类型Void:

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Run Code Online (Sandbox Code Playgroud)

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

或者您可以通过引用Sankar-Ganesh的博客来清楚AsyncTask的作用

那么典型的AsyncTask类的结构如下:

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

    protected void onPreExecute(){ 

    } 
Run Code Online (Sandbox Code Playgroud)

在启动新线程之前执行此方法.没有输入/输出值,因此只需初始化变量或您认为需要做的任何事情.

protected Z doInBackground(X...x){

}
Run Code Online (Sandbox Code Playgroud)

AsyncTask类中最重要的方法.你必须在这里放置你想要在后台做的所有东西,与主要的不同.这里我们有一个输入值来自"X"类型的对象数组(你在标题中看到了吗?我们有"...... extends AsyncTask"这些是输入参数的类型)并从类型中返回一个对象"Z".

protected void onProgressUpdate(是的){

使用方法publishProgress(y)调用此方法,并且通常在要在主屏幕中显示任何进度或信息时使用它,例如显示您在后台执行操作的进度条的进度条.

protected void 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.
Run Code Online (Sandbox Code Playgroud)

我们如何从外部课堂调用此任务?只需以下两行:

MyTask myTask = new MyTask();

myTask.execute(x);
Run Code Online (Sandbox Code Playgroud)

其中x是X类型的输入参数.

一旦我们完成任务,我们就可以从"外部"找到它的状态.使用"getStatus()"方法.

myTask.getStatus(); 我们可以获得以下状态:

RUNNING - 表示任务正在运行.

PENDING - 表示任务尚未执行.

FINISHED - 表示onPostExecute(Z)已完成.

关于使用AsyncTask的提示

不要手动调用onPreExecute,doInBackground和onPostExecute方法.这是由系统自动完成的.

您不能在另一个AsyncTask或Thread中调用AsyncTask.方法execute的调用必须在UI Thread中完成.

onPostExecute方法在UI Thread中执行(这里你可以调用另一个AsyncTask!).

任务的输入参数可以是Object数组,这样您就可以放置所需的任何对象和类型.


liv*_*ove 5

您可以在任务构造函数中传递参数,也可以在调用执行时传递参数:

AsyncTask<Object, Void, MyTaskResult>
Run Code Online (Sandbox Code Playgroud)

第一个参数(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);

        }
    }

}
Run Code Online (Sandbox Code Playgroud)