如何从AsyncTask返回ArrayList?

Fra*_*ero 6 android arraylist android-asynctask

我的MainActivity上有一个AsynkTask方法,它是以下内容:

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

        }
    }
Run Code Online (Sandbox Code Playgroud)

其中,Car它是我在其他已经宣布的对象Class和它的哪个构造函数:

public Car(int idCar, String name)
{
    this.idCar = idCar;
    this.name = name;
}
Run Code Online (Sandbox Code Playgroud)

而且我知道return cars;ArrayList命名返回cars给方法,onPostExecute但我试图ArrayList从那里检索它,但我不能,因为它总是告诉我onPostExecute方法必须Void.

我还在课堂上ArrayList宣布了另一个MainActivity:

ArrayList<Car> totalCars = new ArrayList<Car>();
Run Code Online (Sandbox Code Playgroud)

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

'clone()'在'java.lang.Object'中保护了访问权限

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

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

所以我也尝试将我的值直接添加到totalCars我的doInBackground方法上的ArrayList :

totalCars.add(new Car(1,"Car1");
totalCars.add(new Car(2,"Car2");
totalCars.add(new Car(3,"Car3");
Run Code Online (Sandbox Code Playgroud)

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

new chargeCars().execute();
Run Code Online (Sandbox Code Playgroud)

我的totalCarsArrayList 的大小等于0.

我该怎么办?我完全阻止,我在SO搜索答案,但我找不到任何对我有帮助的东西.

编辑:我的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:我把一些日志看看我的程序究竟是什么,我得到了奇怪的结果:

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

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

可能是什么问题呢?

编辑3:我也试过:

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

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但仍然行不通.ProgressDialog当我尝试Log在我的onCreate方法中使用my时,我也试图确保我的AsyncTask已经完成但它也给了我一个错误(我还有另外一个问题,但是我不知道这是不是一个好习惯在SO中直接引用另一个问题,所以我不在这里发布).

难道我做错了什么?为什么在我的doInBackground它给我正确sizeArrayList和我的onCreate方法不是?

提前致谢!

Bla*_*elt 8

难道我做错了什么?为什么在我的doInBackground中它给了我正确的ArrayList大小和我的onCreate方法呢?

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

让我们在Activity的顶部声明一个接口,并且不要实现这个接口(你需要实现这些方法).当onCarsCompleted被调用时,你就可以打印的正确尺寸的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) {

      }  

}         
Run Code Online (Sandbox Code Playgroud)

现在我们为你的构造函数添加一个构造函数AsyncTask,它将参数作为一个类型的对象OnCarsListener,并且我们保持对作者范围内的对象的成员引用chargeCars,然后onPostExecute我们回传给Activity你的计算结果:

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


}
Run Code Online (Sandbox Code Playgroud)

当然,您需要实例化AsyncTask

new chargeCars(this).execute();