如何从AsyncTask返回ArrayList? [英] How can I return an ArrayList from my AsyncTask?

查看:92
本文介绍了如何从AsyncTask返回ArrayList?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的MainActivity上有一个AsynkTask方法,如下所示:

I have an AsynkTask method on my MainActivity that it's the following:

class chargeCars extends AsyncTask<Void, Integer, ArrayList<Car>> {
        protected void onPreExecute(){
        }
        protected ArrayList<Car> doInBackground(Void... params) {

            ArrayList<Car> cars = new ArrayList<Car>();

            cars.add(new Car(1,"Car1");
            cars.add(new Car(2,"Car2");
            cars.add(new Car(3,"Car3");

            return cars;
        }

        protected void onProgressUpdate(){
        }

        protected void onPostExecute(ArrayList<Car> c){

        }
    }

其中Car是我在另一个Class中声明的对象,它是哪个构造函数:

where Car it's an object that I have declared in another Class and which constructor it's:

public Car(int idCar, String name)
{
    this.idCar = idCar;
    this.name = name;
}

,而且我知道return cars;将名为carsArrayList返回到方法onPostExecute,但是我尝试从那里检索此ArrayList,但我不能,因为它总是对我说方法必须为Void.

and I know that return cars; returns the ArrayList named cars to the method onPostExecute but I tried to retrieve this ArrayList from there and I couldn't because it always said to me that onPostExecute method have to be Void.

在我的MainActivity类中还声明了另一个ArrayList:

I have also another ArrayList declared in my MainActivity class:

ArrayList<Car> totalCars = new ArrayList<Car>();

所以我尝试的是在onPostExecute方法中将cars ArrayList克隆到我的totalCars ArrayList中,但是它给了我一个错误,它说:

so what I tried it's to clone cars ArrayList into my totalCars ArrayList in my onPostExecute method but it gives me an error in which it says that:

'clone()'已保护对'java.lang.Object'的访问

'clone()' has protected access in 'java.lang.Object'

这是试图克隆我的ArrayList的代码:

Here it's the code trying to clone my ArrayList:

protected void onPostExecute(ArrayList<Car> c)
{
    for(Car cr: c)
    {
        totalCars.add(cr.clone());
    }
}

因此,我还尝试将我的值直接添加到我的doInBackground方法上的totalCars ArrayList中:

So I also tried to add my values directly to my totalCars ArrayList on my doInBackground method:

totalCars.add(new Car(1,"Car1");
totalCars.add(new Car(2,"Car2");
totalCars.add(new Car(3,"Car3");

但是当我执行我的AsyncTask方法时:

but when I execute my AsyncTask method:

new chargeCars().execute();

我的totalCars ArrayList的大小等于0.

the size of my totalCars ArrayList it's equals to 0.

我该怎么办?我完全被封锁了,我在SO中搜寻答案,但找不到任何对我有帮助的东西.

What should I do? I'm totally block and I searched in SO for an answer but I couldn't find anything that helps to me.

我的Car类别是:

public class Car {

    private int idCar;
    private String name;

    public Car(){};

    public Car(int idCar, String name)
    {
        this.idCar = idCar;
        this.name = name;
    }

    public void setIdCar(int idCar)
    {
         this.idCar = idCar;
    }

    public int getIdCar()
    {
        return idCar;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }
}

我放了一些日志以查看我的程序到底做了什么,并且得到了奇怪的结果:

EDIT 2: I put some logs to see what exactly does my program and I got strange results:

正如Clairvoyant所说,我使用了他的两种方法,但是它们中的任何一种都有效.我能看到什么?好吧,我看到在onPostExecute方法中,ArrayList在两个方法中都包含值.这里没有问题.

As Clairvoyant said, I use both of his methods but any of them works. What could I saw? Well, I saw that in the onPostExecute method the ArrayList contains values in both of the methods. Here there is no problem.

问题在于,当我在MainActivity类的方法onCreate中执行AsyncTask时,我的ArrayList totalCars里面没有任何值,但是在我的AsyncTask的方法onPostExecute中却有我放入ArrayList中的所有值.

The problem it's that when I execute the AsyncTask in the method onCreate of my MainActivity class, my ArrayList totalCars doesn't have any value inside, but in the method onPostExecute of my AsyncTask it has all the values that I put inside the ArrayList.

可能是什么问题?

我也尝试过:

public class MainActivity extends ActionBarActivity {

   ArrayList<Car> cars = new ArrayList<Car>();

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

    new chargeCars().execute();
    Log.d("Size onCreate: ", "" + cars.size()); //It returns me a 0 -->Incorrect
   }

   class chargeCars extends AsyncTask<Void, Integer, Boolean> {
        protected void onPreExecute(){
        }

        protected ArrayList<Car> doInBackground(Void... params) {

            cars.add(new Car(1,"Car1");
            cars.add(new Car(2,"Car2");
            cars.add(new Car(3,"Car3");

            Log.d("Size: ", "" + cars.size()); //It gives me the size equals to 3 -->Correct 
            return true;

        }

        protected void onProgressUpdate(){
        }

        protected void onPostExecute(boolean c){

        }
    }
}

但是仍然不起作用.我还尝试制作一个ProgressDialog来确保我的AsyncTask在我尝试在onCreate方法中使用我的Log时完成,但是它也给我一个错误(我对此有另一个疑问,但是我不知道直接从另一个问题进行引用是否是SO的良好做法,所以我不在此发布.)

But still doesn't work. I also tried to make a ProgressDialog to be secure that my AsyncTask it's finished when I try to use my Log in my onCreate method but it also gives me an error (I have another question in SO about it but I don't know if it's a good practice in SO to make directly reference from another question so I don't post it here).

我做错什么了吗?为什么在我的doInBackground中它为我提供了ArrayList的正确size而在我的onCreate方法中却没有?

Am I doing something wrong? Why in my doInBackground it gives me the correct size of the ArrayList and in my onCreate method not?

提前谢谢!

推荐答案

我做错什么了吗?为什么在我的doInBackground中,它给了我 正确的ArrayList的大小,在我的onCreate方法中不是吗?

Am I doing something wrong? Why in my doInBackground it gives me the correct size of the ArrayList and in my onCreate method not?

因为执行是异步的,并且UI Thread不能结束AsyncTask的执行以继续其执行流程.要获得结果,请在AsyncTask完成执行时不阻塞UI Thread的情况下,可以使用委托/列表.

Because the execution is asynchronous and the UI Thread doesn't way the end of the execution of your AsyncTask to continue its execution flow. To get the results back, when your AsyncTask finishes its execution, without blocking the UI Thread, you could use a delegate/lister.

让我们在Activity的顶部声明一个接口,让我们不要实现该接口(您将需要实现这些方法).调用onCarsCompleted时,您将能够打印正确尺寸的ArrayList

Let's declare an interface on the top of your Activity, and let't it implement this interface (you'll need to implement the methods). When onCarsCompleted is invoked you'll be able to print the correct size of your ArrayList

 public class MainActivity extends ActionBarActivity implements OnCarsListener {
      public interface OnCarsListener {
          void onCarsCompleted(ArrayList<Car> cars);
          void onCarsError(String error);
      }

      // the other code

      public void onCarsCompleted(ArrayList<Car> cars) {
             Log.d("Size: ", "" + cars.size()); 
      }

      public void onCarsError(String error) {

      }  

}         

现在我们在您的AsyncTask中添加一个构造函数,该构造函数将OnCarsListener类型的对象作为参数,并在chargeCars范围内保留对该对象的成员引用,并且onPostExecute我们进行通讯到Activity计算结果:

now we add a constructor to your AsyncTask, which takes as parameter an object of type OnCarsListener, and we keep a member reference to the object in the scope of chargeCars, and onPostExecute we communicate back to the Activity the results of your computation:

class chargeCars extends AsyncTask<Void, Integer, ArrayList<Car>> {

    private final OnCarsListener mListener;
    ArrayList<Car> cars = new ArrayList<Car>();

    public chargeCars(OnCarsListener listener) {
         mListener = listener;
    } 

    protected void onPreExecute(){
    }

    protected ArrayList<Car> doInBackground(Void... params) {

        cars.add(new Car(1,"Car1");
        cars.add(new Car(2,"Car2");
        cars.add(new Car(3,"Car3");

        Log.d("Size: ", "" + cars.size()); //It gives me the size equals to 3 -->Correct 
        return cars;

    }

    protected void onProgressUpdate(){
    }

    protected void onPostExecute(ArrayList<Car> cars){
         if (mListener != null) {
              mListener.onCarsCompleted(cars);
         } 
    }


}

当然,您需要像这样实例化AsyncTask

And of course, you need to instantiate the AsyncTask like

new chargeCars(this).execute();

这篇关于如何从AsyncTask返回ArrayList?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆