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

我使用 AsyncTask加载作为内部类实现的操作。

onPreExecute()中,我显示了一个加载对话框,然后再次隐藏在 onPostExecute()中。但是对于一些加载操作,我提前知道它们会很快完成,所以我不想显示加载对话框。

我想通过一个布尔参数来表示这一点,我可以将它传递给 onPreExecute(),但是由于某种原因,显然 onPreExecute()没有任何参数。

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

152966 次浏览

可以覆盖构造函数,比如:

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)向异步任务传递方法 为了避免多次对异步任务基础结构(线程、消息传递处理程序、 ...)进行编码,可以考虑将应该在异步任务中执行的方法作为参数传递。下面的示例概述了这种方法。 此外,您可能需要子类化异步任务,以便在构造函数中传递初始化参数。

 /* 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;
}
});
}

为什么,如何以及哪些参数被传递到 Asynctask < > ,详见 给你。我认为这是最好的解释。

Google's Android Documentation Says that :

一个异步任务由3种通用类型(称为 Params、 Progress 和 Result)和4个步骤(称为 onPreExecute、 doInBack、 onProgressUpdate 和 onPostExecute)定义。

AsyncTask 的通用类型:

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

Params,执行时发送到任务的参数的类型。 进度,在后台计算期间发布的进度单元的类型。 结果,背景计算结果的类型。 并非所有类型总是由异步任务使用。要将类型标记为未使用,只需使用类型 Void:

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

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

或者你可以通过引用 Sankar-Ganesh 的博客来清楚 AsyncTask 的角色

Well The structure of a typical AsyncTask class goes like :

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


protected void onPreExecute(){


}

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

protected Z doInBackground(X...x){


}

AsyncTask 类中最重要的方法。你必须把所有想做的事情放在后台,放在和主线程不同的线程里。这里我们有一个来自“ X”类型的对象数组作为输入值(你看到头部了吗?)?我们有“ ... 扩展 AsyncTask”,这些是输入参数的 TYPES) ,并从类型“ Z”返回一个对象。

(Y){

} 这个方法是使用 PublishProgress (y)方法调用的,它通常用于在主屏幕上显示任何进度或信息的时候,比如在后台显示操作进度的进度条。

在 PostExecute (Z z)上的 protected void {

} 此方法在后台操作完成后调用。作为一个输入参数,您将接收 doIn 背景方法的输出参数。

What about the X, Y and Z types?

正如你可以从上面的结构中推断出:

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 () ; 我们可以得到以下状态:

运行-指示任务正在运行。

PENDING-指示任务尚未执行。

FINISHED - Indicates that onPostExecute(Z) has finished.

关于使用 AsyncTask 的提示

不要手动调用 onPreExecute、 doInBack 和 onPostExecute 方法。这是由系统自动完成的。

不能在另一个 AsyncTask 或线程内调用 AsyncTask。方法执行的调用必须在 UI 线程中完成。

OnPostExecute 方法在 UI 线程中执行(在这里您可以调用另一个 AsyncTask!)。

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

You can either pass the parameter in the task constructor or when you call execute:

AsyncTask<Object, Void, MyTaskResult>

第一个参数(Object)在 doInBack 中传递。 第三个参数(MyTaskResult)由 doInBack 返回。您可以将它们更改为所需的类型。这三个点意味着零个或多个对象(或它们的数组)可以作为参数传递。

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);


}
}


}