2010-06-19 56 views
96

我使用AsyncTask加载我作为内部类实现的操作。Android:我如何传递参数给AsyncTask的onPreExecute()?

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

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

明显的解决方法可能是在我的AsyncTask或外部类中创建一个成员字段,我必须在每次加载操作之前设置该成员字段,但这看起来不太优雅。有一个更好的方法吗?

回答

202

您可以覆盖构造函数。喜欢的东西:

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(); 
+3

这正是我现在所做的。我仍然需要一个成员变量,但在AsyncTask中,而不是外部类,如果这就是你的意思。这就是我所做的: 私有类MyAsyncTask extends AsyncTask private boolean showLoading; public MyAsyncTask(boolean showLoading)super(); this.showLoading = showLoading; //做的东西 } 保护无效onPreExecute(){ 如果(showLoading){// ... }} // doInBackground()等。 } – 2010-06-20 21:48:55

+1

是的,这是非常想法:) – Felix 2010-06-20 22:10:35

+3

这是正确的答案 – 2011-10-07 07:39:05

49

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)将方法传递给异步任务 为了避免多次编写async-Task基础结构(线程,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; 
     } 
    });  
} 
8

为什么,参数是如何和传递的AsyncTask <>,看到的细节here。我认为这是最好的解释。

谷歌的Android文档说:

异步任务由3种泛型类型定义,所谓的参数,可以进展和结果,以及4个步骤,称为onPreExecute,doInBackground,onProgressUpdate和onPostExecute。

的AsyncTask的通用类型:

由异步任务中使用的三种类型的有以下几种:

PARAMS,在执行时发送给任务的参数的类型。 进度,在后台计算期间发布的进度单位的类型。 结果,后台计算结果的类型。 并非所有类型始终由异步任务使用。为了纪念一个类型为未使用时,只需使用void类型:

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

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

也可以清除最新的AsyncTask由闯民宅桑卡尔 - Ganesh的博客

好作用典型的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 - 表示任务正在运行。

挂起 - 表示该任务尚未执行。

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

提示有关使用的AsyncTask

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

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

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

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

0

您可以传递参数的任务建构或当你调用execute:

AsyncTask<Object, Void, MyTaskResult> 

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

     } 
    } 

}