Передача аргументов в AsyncTask и возвращение результатов - PullRequest
36 голосов
/ 16 ноября 2010

У меня есть приложение, которое выполняет долгие вычисления, и я хотел бы показать диалог прогресса, когда это будет сделано.До сих пор я обнаружил, что могу делать это с потоками / обработчиками, но не сработал, и затем я узнал о 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 и получить список массивов строк «result»назад от этого.И класс 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 (и использовать их там), икак вернуть список массивов для использования в методе main (список массивов «result»)?

Ответы [ 5 ]

64 голосов
/ 16 ноября 2010

Измените свой метод, чтобы он выглядел так:

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);
12 голосов
/ 21 мая 2012

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

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

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

4 голосов
/ 30 октября 2012

Я согласен с Леандером в этом вопросе.

звоните:

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 голос
/ 24 января 2013

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

открытый класс calc_stanica extends 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 голосов
/ 23 апреля 2015

Вы можете получить возвращаемые результаты, например: 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();

Надеемся, что это поможет.

...