2015-06-09 2 views
4

У меня есть метод AsynkTask на моем MainActivity, что это следующее:Как я могу вернуть ArrayList из моей AsyncTask?

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 с именем cars в метод onPostExecute, но я попытался извлечь из этого ArrayList, и я не мог, потому что он всегда говорил мне, что onPostExecute метод должен быть Void.

Я также другой ArrayList заявил в своем MainActivity классе:

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

так что я пытался это клонировать cars ArrayList в моей totalCars ArrayList в моем onPostExecute метод, но он дает мне ошибку, в которой он говорит, что :

'клон()' имеет защищенный доступ в 'java.lang.Object'

Вот это код пытается клонировать мой ArrayList:

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

размер моего totalCars ArrayList он равен 0.

Что мне делать? Я полностью блокирован, и я искал в SO для ответа, но я не мог найти ничего, что мне помогло.

EDIT: Мой 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: я ставлю некоторые журналы, чтобы увидеть, что именно делает мою программу и я получил странные результаты:

Как Clairvoyant сказал, Я использую оба его метода, но любой из них работает. Что я мог видеть? Ну, я видел, что в методе onPostExecute ArrayList содержит значения в обоих методах. Здесь нет проблем.

проблема это то, что когда я исполню AsyncTask в методе onCreate моего MainActivity класса, мой ArrayList totalCars не имеет никакого значения внутри, но в методе onPostExecute моего AsyncTask имеет все значения, которые я положил внутрь ArrayList.

В чем может быть проблема?

EDIT 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 закончен, когда я пытаюсь использовать мой Log в моем методе onCreate, но он также дает мне ошибку (у меня есть еще один вопрос в SO об этом, но я не знаю, хорошая практика в SO, чтобы напрямую ссылаться на другой вопрос, поэтому я не размещаю его здесь).

Я что-то не так? Почему в моем doInBackground он дает мне правильный sizeArrayList и в моем методе onCreate нет?

Заранее благодарен!

+1

просто объявить «ArrayList автомобили» за пределами asynTask, а затем добавить свои автомобили без возвращения ничего. – AnixPasBesoin

+0

@AnixPasBesoin У меня есть myArrayList 'totalCars' вне моей AsyncTask, и когда я ничего не возвращаю и добавляю объекты непосредственно к нему, он также не работает. –

+0

Вы отлаживаете свой код ??? – Pankaj

ответ

6

я делаю что-то не так? Почему в моем doInBackground это дает мне правильный размер ArrayList, а в моем методе onCreate нет?

Поскольку исполнение является асинхронным и UI Thread не путь конца выполнения вашего AsyncTask продолжать его поток выполнения. Чтобы вернуть результаты, когда ваш AsyncTask завершит выполнение, не блокируя UI Thread, вы можете использовать делегат/листер.

Давайте объявим интерфейс в верхней части вашей деятельности и дадим ему реализовать этот интерфейс (вам нужно будет реализовать методы). Когда 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();

+0

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перемещен в чат] (http://chat.stackoverflow.com/rooms/80801/discussion-on-answer-by-blackbelt-how-can-i-return-an-arraylist-from-my- asynctas). –

2

Метод 1: Не использовать клон просто использовать объект добавить:

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

Способ 2: сделать метод, который будет вызываться 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 
} 
+0

Я пробовал с вашим первым методом, и он не работает. Если я помещаю 'super.onPostExecute();' он дает мне ошибку, которая говорит: ''onPostExecute (java.util.ArrayList )' in 'android.os.AsyncTask' не может применяться к '()' ' –

+0

Если я уйду из него, у меня нет никаких проблем с моей проблемой. У меня также есть 2 сомнения: почему вы используете 'super.onPostExecute()' и что вы имеете в виду с // кодом для дальнейшего выполнения? Теперь я попытаюсь использовать второй метод. Спасибо! –

+0

Установить ArrayList как параметр в super.onPostExecute (c); – Pankaj

Смежные вопросы