2014-09-17 3 views
0

В настоящее время я разрабатываю приложение, которое подключается к веб-сайту, чтобы получить некоторую информацию (очень мало информации), и я использую Asynctask с HttpClient внутри этого, чтобы получить эту информацию. В основном потоке (UI) я использую runnable плюс обработчик, чтобы проверить, завершена ли Asynctask и, если это так, обрабатывать входящую информацию.Проблемы с подключением к Asynctask

Проблема: иногда Asynctask, похоже, не выполняет задачу, поэтому Handler plus Runnable проверяет ее навсегда без ответа. Это не проблема с сайтом, поскольку я тестировал его на локальном веб-сайте с помощью Xampp. Мне кажется, что я не делаю то, что должно быть.

Я «решаю» проблему, заставляя приложение закрываться через диспетчер приложений Android (приложение принимает менее 1 итерации для получения информации), но я не хотел бы говорить людям, которые будут использовать его : «Эй, в случае проблемы, заставить приложение закрыться через диспетчер приложений», я хотел бы, чтобы приложение запускалось без проблем, поэтому я прошу вас о помощи. :)

Вот код:

public class Postman extends AsyncTask<String,String,String> { 

@Override 
protected String doInBackground(String... s) { 
    HttpClient client = new DefaultHttpClient(); 
    HttpPost post = new HttpPost("http://website.com/" + s[0]); 
    List<NameValuePair> pairs = new ArrayList<NameValuePair>(); 
    for(int i = 1; i < s.length; i++){ 
     pairs.add(new BasicNameValuePair(Integer.toString(i),s[i])); 
    } 
    try { 
     post.setEntity(new UrlEncodedFormEntity(pairs)); 
     HttpResponse r = client.execute(post); 
     String res = EntityUtils.toString(r.getEntity()); 
     return res; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
} 

Этот класс я использую для общения с веб-сайтом. Я создаю объект Почтальон то я использую postman.execute («phpPageToCommunicate.php», + Params) ;, то я использую следующий код, чтобы проверить, если он уже закончил или нет:

final Handler h = new Handler(); 
Runnable r = new Runnable(){ 
@Override 
public void run() { 
    if(postman.getStatus() == AsyncTask.Status.FINISHED()){ 
     // some code 
    }else{ 
     h.postDelayed(this,1000); 
    } 
} 
}; 
h.postDelayed(r,1500); 

Я уверен, «Я делаю что-то не так, но я не знаю, что, поэтому я искренне прошу вас о помощи

Приветствия!

+0

вы можете держать флаг в postexceute из AsyncTask, который говорит, что если ур задача Isnt завершения и может показать предупреждение диалог с пользователем .. – KOTIOS

+0

Вместо того, чтобы другой поток проверка выполнения AsyncTask, почему бы не использовать метод OnPostExecute для обработки результата и выполнения обратных вызовов? Так предполагается использование AsyncTask. – personne3000

+0

Если это внутренний класс вашей «Деятельности», просто используйте 'onPostExecute()', как было предложено. Если это отдельный класс, тогда [см. Этот ответ об использовании интерфейса] (http://stackoverflow.com/questions/18517400/inner-class-can-access-but-not-update-values-asynctask/18517648#18517648) чтобы вернуть результат в вашу «Активность». Для этого вам не нужен «Handler». – codeMagic

ответ

1

Вы делаете это очень неправильный фактически. Существует способ onPostExecute, который вы можете переопределить в своем классе AsyncTask и в нем делать то, что вам нужно. Все в этом методе выполняется в потоке пользовательского интерфейса, поэтому вам не нужно заботиться об этом.

Третий класс - это фактически тот результат, который вы ожидаете в своем onResult. Так что в вашем случае вы проходите <String, String, String>, поэтому ваш onPostExecute будет onPostExecute(String result).

+0

Большое спасибо! Мое приложение действительно быстрее, и проблема намного реже. Я продолжу учебу, чтобы получить лучшие результаты. –

0

Хорошо вы делаете ASync задачу неправильно

private class GetInfo extends 
      AsyncTask<String, Void, String> { 

     @Override 
     protected String doInBackground(String... strUrl) { 
      // Do something with strUrl 
      // Store the result in res variable(String) 

      return res; //Returns this to onPostExecute 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      // Set Data to View or save it 
     } 

    } 

и в основной вызов резьбы

new GetInfo().execute(//string to process); 

процесса метод doInBackground данных (получить данные из API или что-то в ваш случай) .. вся тяжелая работа здесь, что требуется время.

результат сохраняется в виде строки, и эта строка returend в onPostExecute, где он может быть установлен в целях сохранения или в БД и т.де ..

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

EDIT: также существует еще один метод, называемый onPreExecution(), который позволяет инициализировать переменные и прочее, если вы хотите, до вызова метода doInBackground.

Также я хотел бы указать <String, Void, String>, здесь 1-я строка - это тип данных. Задача Async будет получена из метода execute в основном потоке, вторая Void будет для выполнения некоторых операций, пока работает в backgorud. например, обновление индикатора выполнения и т. д., а 3-я строка будет типом данных, которые doInBackground вернется к методу postexecute.

Plese читать документацию @ developers.android для получения более подробной информации

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