2012-05-18 3 views
0

Я сделал приложение, которое отправляет запрос на веб-сервер за указанный интервал и получает XML-данные. Затем он анализирует данные XML, получает информацию с телефона (текстовые сообщения, контакты или что-то подобное) и отправляет их обратно на сервер с запросом на отправку по электронной почте.Android/Java: Как реализовать AsyncTask?

Проблема заключается в том, что для получения информации обычно требуется несколько секунд, что часто приводит к сбою приложения. Появляется диалоговое окно, в котором говорится, что приложение перестало отвечать на запросы и спрашивает, хочу ли я закрыть приложение или ждать, если я нажму, подождите, пока он снова начнет работать.

Является ли AsyncTask правильным решением этой проблемы?

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

+0

check [this] (http://www.vogella.com/articles/AndroidPerformance/article.html) – silwar

ответ

1

Я также реализовал нечто похожее, которое вы пытаетесь. Это отправка запроса на сервер, получение ответа XML, анализ XML, отображение результата. View This. Для этого я использовал AsyncTask.

Вот как я реализовал его с помощью AsynTask

private class AsyncClass extends AsyncTask<Void, Void, Bundle>{ 
    @Override 
protected Bundle doInBackground(Void... arg0) { 
    Bundle b=startProcess();   

// startBundle() method do all the processing and return result in a bundle. You can as many methods from within startBundle() method 

    return b; 
}  

@Override 
protected void onPostExecute(Bundle result) { 
    Log.d(TAG , "In onPostExecute"); 
    dialog.dismiss(); 
    if(result==null) 
     Toast.makeText(cont, "Can't process query.\nTry again later.", Toast.LENGTH_LONG).show(); 
    else{ 
     Intent in = new Intent(cont, QueryResultDisplay.class); 
     Log.d(TAG , "Displaying"); 
     in.putExtras(result);   
     cont.startActivity(in);   
    } 
} 
+0

Итак, если я правильно понимаю, startBundle() - это еще один метод в классе AsyncClass, который выполняет всю тяжелую работу ? Это кажется многообещающим. – qwerty

+0

А также я могу назвать AsyncTask из любых классов? Как и сейчас, у меня есть класс Main, который показывает GUI, а затем я настраиваю AlarmManager, который вызывает BroadcastReceiver каждые X минут. BroadcastReceiver находится в другом классе, и в настоящее время это класс, который выполняет всю тяжелую работу. Могу ли я переместить все трудовые методы в класс AsyncTask и вызвать класс AsyncTask из BroadcastReceiver? Извините, если это сбивает с толку, я надеюсь, что вы его получите. – qwerty

+0

Класс @qwerty AsyncTask реализуется как подкласс для любого основного класса. Из метода основного класса мы можем вызвать AsyncTask, написав новый AsyncClass().выполнить(); А также не тот startBundle в этом случае был методом в основном классе. Вы можете вызвать метод основного класса из вашего широковещательного приемника, который далее вызовет asyncTask, используя «новый AsyncClass(). Execute();» – Pargat

0

Да, вы можете использовать AsyncTask.

Код, вызываемый в doInBackground(), не должен касаться пользовательского интерфейса.

Вы можете коснуться темы пользовательского интерфейса publishProgress().

1

Я даю вам краткое описание вашей проблемы.

Есть много вероятности того, что вы не получите данные от сервера

  1. , если ваша скорость сети очень медленно, и вы пытаетесь получить всю информации от сервера и XML данных, то в этом случае, если сетевой сбой, то он покажет вам ошибку

  2. , если вы делаете запрос на эту страницу, которая не находится в сервере

Теперь, если вы столкнулись с проблемой в коде, тогда я даю вам полный код класса AsyncTask, который был реализован в моем проекте, и он работает нормально.

private class GetLoginResponse extends AsyncTask<Void, Void, Boolean> { 
    private ProgressDialog progressDialog; 
    private String email; 
    private String password; 

    public GetLoginResponse(String emailId, String paswd) { 
     this.email = emailId; 
     this.password = paswd; 
    } 

    @Override 
    protected void onPreExecute() { 
     progressDialog = ProgressDialog.show(LoginActivity.this, "", 
       "Loading....", true, false); 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 

     try { 
      DefaultHttpClient httpclient = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(url); 
          HttpResponse response = httpclient.execute(httpGet); 
     //here u can check the reponse is ok and 200 
         } catch (NetworkException e) { 
      isNetworkError = true; 
     } 
     return false; 
    } 

    @Override 
    protected void onPostExecute(Boolean data) { 
     progressDialog.dismiss(); 
     System.out.println("lOGIN RESPONSE for email = " + email + data); 
    } 
}// end AsyncTask 

Это поможет решить вашу проблему.

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