2010-11-16 3 views
34

У меня есть приложение, которое выполняет некоторые длительные вычисления, и я хотел бы показать диалог прогресса, когда это будет сделано. До сих пор я обнаружил, что могу сделать это с помощью потоков/обработчиков, но не работал, а затем узнал о AsyncTask.Передача аргументов AsyncTask и возвращаемые результаты

В моем приложении я использую карты с маркерами на нем, и я применил функцию onTap для вызова метода, который я определил. Метод создает диалог с кнопками Да/Нет, и я бы хотел позвонить AsyncTask, если нажата кнопка «Да». Мой вопрос заключается в том, как передать ArrayList<String> в AsyncTask (и работать с ним там), и как вернуть новый ArrayList<String> как результат из AsyncTask?

Код метода выглядит следующим образом:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 

ArrayList<String> passing = new ArrayList<String>(); 
passing.add(itemdesc); 
passing.add(curloc); 

ArrayList<String> result = new ArrayList<String>(); 

new calc_stanica().execute(passing,result); 

String minim = result.get(0); 
int min = Integer.parseInt(minim); 

String glons = result.get(1); 
String glats = result.get(2); 

double glon = Double.parseDouble(glons); 
double glat = Double.parseDouble(glats); 

GeoPoint g = new GeoPoint(glon, glat); 
String korisni_linii = result.get(3); 

Итак, как вы видите, я хотел бы послать строку списка массива «проходящее» в AsyncTask, и получить «результат» строка массив назад. А класс calc_stanica AssycTask выглядит следующим образом:

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> { 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(baraj_mapa.this); 
     dialog.setTitle("Calculating..."); 
     dialog.setMessage("Please wait..."); 
     dialog.setIndeterminate(true); 
     dialog.show(); 
    } 

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) { 

     //Some calculations... 

     return something; //??? 
    } 

    protected void onPostExecute(Void unused) { 
     dialog.dismiss(); 
    } 

Так что мой вопрос заключается в том, чтобы получить элементы «ближнего» списка массива в методе AsyncTask doInBackground (и использовать их там), и как вернуть список массива использовать в основном методе (список массива «результат»)?

ответ

61

Изменить способ выглядеть следующим образом:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 
ArrayList<String> passing = new ArrayList<String>(); 
passing.add(itemdesc); 
passing.add(curloc); 
new calc_stanica().execute(passing); //no need to pass in result list 

и изменение реализации задачи асинхронной

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> { 
ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(baraj_mapa.this); 
     dialog.setTitle("Calculating..."); 
     dialog.setMessage("Please wait..."); 
     dialog.setIndeterminate(true); 
     dialog.show(); 
    } 

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) { 
     ArrayList<String> result = new ArrayList<String>(); 
     ArrayList<String> passed = passing[0]; //get passed arraylist 

     //Some calculations... 

     return result; //return result 
    } 

    protected void onPostExecute(ArrayList<String> result) { 
     dialog.dismiss(); 
     String minim = result.get(0); 
     int min = Integer.parseInt(minim); 
     String glons = result.get(1); 
     String glats = result.get(2); 
     double glon = Double.parseDouble(glons); 
     double glat = Double.parseDouble(glats); 
     GeoPoint g = new GeoPoint(glon, glat); 
     String korisni_linii = result.get(3); 
    } 

UPD:

Если вы хотите иметь доступ к задаче исходного контекста, самым простым способом было бы переопределить onPostExecute на месте:

new calc_stanica() { 
    protected void onPostExecute(ArrayList<String> result) { 
     // here you have access to the context in which execute was called in first place. 
     // You'll have to mark all the local variables final though.. 
    } 
}.execute(passing); 
+0

Благодарим вас за ответ, но у меня есть еще одна вещь, чтобы спросить. Если я определяю int min = Integer.parseInt (minim); например, в классе AsyncTask onPostExecute(), как я могу получить к нему доступ из моего метода основного класса? Когда я меняю его так, я получаю ошибку «мин не может быть разрешен» в методе основного класса. –

+2

@Bojan Ilievski: Просто сделайте свою переменную min глобальной. – Wroclai

+0

Спасибо за ваши ответы еще раз, я решил свои проблемы ... –

12

Зачем вам передавать ArrayList? Должна быть возможность просто уравнять выполнить с Params непосредственно:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 
new calc_stanica().execute(itemdesc, curloc) 

Вот как varrargs работу, не так ли? Создание переменной ArrayList для передачи переменной - это двойная работа.

+0

Я полностью согласен с Leander здесь. В любом случае, чтобы изменить правильный флажок ответа? –

4

Я как бы согласен с leander на этом.

вызов:

new calc_stanica().execute(stringList.toArray(new String[stringList.size()])); 

задача:

public class calc_stanica extends AsyncTask<String, Void, ArrayList<String>> { 
     @Override 
     protected ArrayList<String> doInBackground(String... args) { 
      ... 
     } 

     @Override 
     protected void onPostExecute(ArrayList<String> result) { 
      ... //do something with the result list here 
     } 
} 

Или вы могли бы просто сделать список результатов параметр класса и заменить ArrayList с булево (успех/неудача);

public class calc_stanica extends AsyncTask<String, Void, Boolean> { 
     private List<String> resultList; 

     @Override 
     protected boolean doInBackground(String... args) { 
      ... 
     } 

     @Override 
     protected void onPostExecute(boolean success) { 
      ... //if successfull, do something with the result list here 
     } 
} 
1

Я не делаю так. Мне легче перегрузить конструктор класса asychtask ..

общественного класса calc_stanica расширяет AsyncTask>

String String mWhateveryouwantToPass; 

public calc_stanica(String whateveryouwantToPass) 
{ 

    this.String mWhateveryouwantToPass = String whateveryouwantToPass; 
} 
/*Now you can use whateveryouwantToPass in the entire asynchTask ... you could pass in a context to your activity and try that too.*/ ... ... 
0

Вы можете получить возвращения результатов как то: AsyncTask класса

@Override 
protected Boolean doInBackground(Void... params) { 
    if (host.isEmpty() || dbName.isEmpty() || user.isEmpty() || pass.isEmpty() || port.isEmpty()) { 
     try { 
      throw new SQLException("Database credentials missing"); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    try { 
     Class.forName("org.postgresql.Driver"); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 

    try { 
     this.conn = DriverManager.getConnection(this.host + ':' + this.port + '/' + this.dbName, this.user, this.pass); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 

    return true; 
} 

приемный класс:

_store.execute(); 
boolean result =_store.get(); 

надеясь, что я т поможет.