【问题标题】:How can I return an ArrayList from my AsyncTask?如何从我的 AsyncTask 返回一个 ArrayList?
【发布时间】:2015-08-24 05:12:05
【问题描述】:

我的 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; 将名为 carsArrayList 返回到方法 onPostExecute 但我试图从那里检索这个 ArrayList 但我不能,因为它总是对我说 @987654330 @方法必须是Void

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

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

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

'clone()' 在 'java.lang.Object' 中具有受保护的访问权限

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

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

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

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

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

new chargeCars().execute();

我的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;
    }
}

编辑2:我放了一些日志来看看我的程序到底做了什么,结果很奇怪:

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

问题在于,当我在 MainActivity 类的方法 onCreate 中执行 AsyncTask 时,我的 ArrayList totalCars 内部没有任何值,但在我的 AsyncTask 的方法 onPostExecute 中它有我放入 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){

        }
    }
}

但还是不行。我还尝试创建一个ProgressDialog 以确保我的 AsyncTask 在我尝试在我的onCreate 方法中使用我的Log 时完成,但它也给了我一个错误(我有另一个关于它的问题,但我不知道直接从另一个问题中引用是否是一种好的做法,所以我不在这里发布)。

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

提前致谢!

【问题讨论】:

  • 只需在你的 asynTask 之外声明“ArrayList cars”,然后添加你的汽车而不返回任何东西。
  • @AnixPasBesoin 我的 ArrayList totalCars 在我的 AsyncTask 之外,当我不返回任何内容并将对象直接添加到其中时,它也不起作用。
  • 你的代码调试了吗???
  • @Clairvoyant 我在执行 AsyncTask 后放了一些日志,看看它给了我什么。
  • @Clairvoyant 我用你的方法看到的结果编辑了我的问题。可能是什么问题?

标签: android arraylist android-asynctask


【解决方案1】:

方法一: 不要使用克隆,只需使用对象添加:

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

方法二: 创建一个方法,onPostExceute() 获得 ArrayList 后将调用该方法

 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
}

【讨论】:

  • 我尝试了你的第一种方法,但它不起作用。如果我输入super.onPostExecute();,它会给我一个错误,上面写着:'onPostExecute(java.util.ArrayList&lt;com.example.user.project.Car&gt;)' in 'android.os.AsyncTask' cannot be applied to '()'
  • 如果我退出它,我的问题没有任何解决办法。我也有 2 个疑问:你为什么使用 super.onPostExecute() 以及 //Code for further execution 是什么意思?现在我要试试你的第二种方法。谢谢!
  • 在super.onPostExecute(c)中设置ArrayList为参数;
  • 如果你想在设置arraylist之后放置任何代码来执行,你可以这样做
  • 我把 super.onPostExecute 像你对我说的那样,第一种方法也让我的 ArrayList 的大小等于 0。
【解决方案2】:

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


}

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

new chargeCars(this).execute();

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多