如何从AsyncTask返回ArrayList?

时间:2015-06-09 11:47:04

标签: 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){

        }
    }

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

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

我知道return cars;会将名为ArrayList的{​​{1}}返回给方法cars,但我尝试从那里检索此onPostExecute而我无法&# 39;因为它总是告诉我ArrayList方法必须是onPostExecute

我还在我的Void课程中声明了另一个ArrayList

MainActivity

所以我尝试将ArrayList<Car> totalCars = new ArrayList<Car>(); ArrayList克隆到我的cars方法中的totalCars ArrayList中,但它给出了一个错误,其中它表示:

  

&#39;克隆()&#39;在java.lang.Object&#39;中保护了访问权限。

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

onPostExecute

所以我也尝试将我的值直接添加到protected void onPostExecute(ArrayList<Car> c) { for(Car cr: c) { totalCars.add(cr.clone()); } } 方法上的totalCars ArrayList:

doInBackground

但是当我执行totalCars.add(new Car(1,"Car1"); totalCars.add(new Car(2,"Car2"); totalCars.add(new Car(3,"Car3"); 方法时:

AsyncTask

我的new chargeCars().execute(); ArrayList的大小等于0。

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

编辑:我的totalCars课程:

Car

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

正如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; } } 所说,我使用他的两种方法但其中任何一种都有效。我能看到什么?好吧,我在Clairvoyant方法中看到,ArrayList包含两个方法中的值。这里没有问题。

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

可能是什么问题?

编辑3:我也尝试过:

onPostExecute

但仍然无法奏效。当我尝试在我的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时,我还试图让Log确保我的AsyncTask已经完成,但它也给了我一个错误(我还有另外一个问题,但是我不知道在SO中做一个好的做法是直接从另一个问题引用,所以我不在这里发布。

我做错了吗?为什么在我的onCreate中,它为我提供了doInBackground sizeArrayList方法中的正确值?

提前致谢!

2 个答案:

答案 0 :(得分:7)

  

我做错了吗?为什么在我的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) {

      }  

}         

现在我们向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); } } }

new chargeCars(this).execute();

当然,您需要实例化

之类的AsyncTask

{{1}}

答案 1 :(得分:2)

方法1: 不要使用clone只使用object来添加:

protected void onPostExecute(ArrayList<Car> c)
{
       super.onPostExecute();
    for(Car cr: c)
    {
        totalCars.add(cr);
    }
       //Code for further execution
}

方法2: 创建一个方法,在获得ArrayList

之后由onPostExceute()调用
 protected void onPostExecute(ArrayList<Car> c)
    {
     super.onPostExecute();
       setValues(c);
    }

private void setValues(ArrayList<Car> c){
      for(Car cr: c)
        {
            totalCars.add(cr);
        }
 //Code for further execution
}