Вопрос по android, android-asynctask, string – Как получить строку обратно из AsyncTask?

49

У меня есть следующий класс:

public class getURLData extends AsyncTask<String, Integer, String>{

@Override
protected String doInBackground(String... params) {
    String line;
    try {  
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(params[0]);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        line = EntityUtils.toString(httpEntity);

    } catch (UnsupportedEncodingException e) {
        line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
    } catch (MalformedURLException e) {
        line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
    } catch (IOException e) {
        line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
    }
    return line;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
}

}

И я пытаюсь назвать это так:

String output = null;
output = new getURLData().execute("http://www.domain.com/call.php?locationSearched=" + locationSearched);

Но выходная переменная не получает данные, вместо этого я получаю ошибку:

Type mismatch: cannot convert from AsyncTask<String,Integer,String> to String
с чего ты взял, ты должен сделатьsuper.onPostExecute(result); ? Я не ставил эту строку и все еще работает! Francisco Corrales Morales

Ваш Ответ

7   ответов
0

Этот ОДИН ЛАЙНЕР работал для меня:

String result = MyasyncTask.execute(type, usrPhoneA, usrPWDA).get();
Возвращает результат операции в переменной «result» после того, как PHP обрабатывает функцию входа в систему. Я читал, что это делает его не асинхронной задачей, но в моем случае это нормально.
Как это может работать, когда он возвращает переменную AsycTask?
Я получил переменную asynctask и мало что использовал
18

Я скорее создаю обратный вызов, чем блокирую поток пользовательского интерфейса. В вашем классе создайте метод, который будет вызываться при поступлении данных. Например:

private void setData(String data){
    mTextView.setText(data);
}

Затем в AsyncTask реализуем onPostExecute:

@Override
protected void onPostExecute(String result) {
    setData(result);
}

И тогда где-то в коде просто выполнить задачу:

new getURLData().execute(...

Когда задача завершается, вызывается setData и заполняется mTextView.

AsyncTask.get () заблокирует ваш пользовательский интерфейс, поэтому нет причин использовать AsyncTask.

отлично, но как мне позвонитьsetData из AsyncTask, если этот метод находится в другой деятельности (тот, который делает.execute) ?
@FranciscoCorralesMorales Лучше определить интерфейс, чтобы использовать его следующим образом:stackoverflow.com/a/12575319/4616096
Вы не т. Просто делай то, что тебе нужно вonPostExecute()
0

В следующем коде я получаю String (directorName) от AsyncTask.

public class GetDirector {
    String id;
    private String baseURL = "http://www.omdbapi.com/?i=";
    private String finalURL = "";
    String theDirector;

    public GetDirector(String imdbID) throws ExecutionException, InterruptedException {
        id= imdbID;
        finalURL = baseURL + id + "&plot=full&r=json";
        System.out.println("GetDirector. finalURL= " + finalURL);
        theDirector = new GetDirectorInfo().execute().get();
    }

    public String getDirector (){
        return theDirector;
    }

    private class GetDirectorInfo extends AsyncTask<Void, Void,String> {
        @Override
        protected String doInBackground(Void... params) {
            String directorName = null;

            ServiceHandler sh = new ServiceHandler();

            // Making a request to url and getting response
            String jsonStr = sh.makeServiceCall(finalURL, ServiceHandler.GET);
            System.out.println("Act_DetailsPage. jsonStr= " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject everything = new JSONObject(jsonStr);

                    directorName = everything.getString(JSON_Tags.TAG_DIRECTOR);
                    System.out.println("directorName= "+ directorName);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("Inside GetDirector. Couldn't get any data from the url");
            }
            return directorName;
        }
    }
}
Используяget вы идете синхронно, тем самым побеждая всю цель AsyncTask, которая заключается в асинхронном выполнении.
107

Методexecute возвращаетAynscTask сам нужно позвонитьget:

output =
    new getURLData()
        .execute("http://www.example.com/call.php?locationSearched=" + locationSearched)
        .get();

Это запустит новую тему (черезexecute) при блокировке текущего потока (черезgetдо тех пор, пока работа из нового потока не будет завершена и результат не будет возвращен.

Если вы сделаете это, вы просто повернулиasync задача вsync один.

Однако проблема с использованиемget в том, что, поскольку он блокирует, он должен вызываться в рабочем потоке. Тем не мение,AsyncTask.execute() должен быть вызван в главном потоке. Таким образом, хотя этот код может работать, вы можете получить нежелательные результаты. Я также подозреваю, чтоget() Google не прошел тестирование, и вполне возможно, что они внесли ошибку где-то вдоль линии.

Ссылка:AsyncTask.get

Боже мой, это становится все сложнее, чем дальше я захожу ... Все, что я хочу сделать, - это когда пользователь нажимает кнопку, он загружает экран прямым способом, а затем отображает контент из http, когда он закончил. Как это сделать? Paul
Хотелось бы, чтобы это было так, но если я перейду к методу onPostExecute, у меня больше не будет переменных params, и возникнет больше проблем с возвратом строки. Я ценю вашу помощь, но это заняло у меня часы, я действительно думаю, что это безнадежное дело. Paul
Спасибо за вашу помощь и терпение. Мне удалось заставить это работать! Хороший :) Paul
@Paul: Все, что вам нужно сделать после исполнения, сделайте это наonPostExecute, Являетсяthat просто...
@Paul: Вы можете добавить конструкторgetURLData который берет параметры и сохраняет их как членов класса, тогда они доступны на вашемonPostExecute метод.
0

Единственный способ отправить данные изAsyncTask чтобы интерфейс без болиэфирное масло или жеСобытие автобус. Зарегистрируйте метод, который будет обрабатывать результат в@Subscribe аннотация в пользовательском интерфейсе иpost message с результатом к нему вonPostExecute метод вашегоAsyncTask.

0

Добавьте параметр контекста в конструктор задачи, который будет ссылаться на объект, в котором вы будете хранить результирующие данные.

class PopulateArray extends AsyncTask<Integer, Integer, ArrayList<String>>
{
    Context _context; // context may be what ever activity or object you want to store result in
    PopulateArray(Context context)
    {
        _context = context;
    }
    @Override
    protected ArrayList<String> doInBackground(Integer... integers)
    {
        ArrayList<String> data = new ArrayList<String>();
        //manipulate
        return data;
    }

    @Override
    protected void onPostExecute(ArrayList<String> strings)
    {
        _context.setData(strings);
    }
}
4

Если пользователь нажимает кнопку, а затем должен ждать содержания, что они делают между тем?

Почему бы не сделать это:

User clicks button. You check for connectivity. If the user isn't connected to the Internet, tell them. You start an IntentService by sending an Intent to send the HTTP request. When the request finishes, you post a notification. The user clicks the notification, which returns to an Activity that can do the next step.

Это позволяет пользователю отключаться и делать что угодно во время обработки запроса.

IntentService работает в фоновом режиме в своем собственном потоке. Когда он получает Intent, он запускает onHandleIntent (). Когда этот метод завершаетс, служба кэшируетс: она не активна, но она может быстро перезапуститьс, когда придет следующее намерение.

Похожие вопросы