15

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

private class MyTask extends AsyncTask<String, Void, String> 
{ 
    private int e = 0; 

    @Override 
    protected String doInBackground(String... params) 
    { 
     try 
     { 
      URL url = new URL("http://www.example.com/"); 
     } 
     catch (MalformedURLException e) 
     { 
      e = 1; 
     } 

     // Other code here... 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    { 
     if (e == 1) 
      Log.i("Some Tag", "An error occurred."); 

     // Perform post processing here... 
    } 
} 

Я считаю, что переменная е майе записывается/доступ как главного и рабочего потока. Как я знаю, onPostExecute() будет запущен только после завершения doInBackround(), могу ли я опустить любую синхронизацию?

Это плохой код? Есть ли согласованный или правильный способ обработки исключений в AsyncTask?

+1

возможно дубликат [AsyncTask и обработки ошибок на Android] (http://stackoverflow.com/questions/1739515/asynctask-and-error-handling-on-android) – blahdiblah

ответ

3

Я делаю это в своих приложениях, я думаю, что нет лучшего способа.

Вы также можете прочитать об этом Mark Murphy answer.

+0

Если это вызывает не проблемы, тогда я счастлив! – Leo

2

Это гарантированно работает даже на архитектуре SMP. Вся синхронизация выполняется для вас. Однако было бы лучше использовать возвращаемое значение для этого.

+1

В фактическом коде я использую пользовательский объект в качестве типа возвращаемого значения, который на самом деле не предоставляет информацию об исключении. Я полагаю, что я не могу перегрузить функцию onPostExecute() 'очень легко? – Leo

+4

Прежде всего, doInBackground должен возвращать объект того же типа, что и параметр inPostExecute(). Затем вы можете просто создать собственный класс для инкапсуляции результата + исключение: class ResultHolder {Exception e; MyResult r; } –

2

Я думаю, что ваш код будет работать, но уже есть некоторая обработка ошибок, встроенная в класс AsyncTask.

Вы можете избежать использования дополнительной переменной с использованием метода cancel() и метода его обработчика onCancelled(). Когда вы вызываете отмену в методе doInBackground() метод onCancelled в потоке пользовательского интерфейса. Если вы вызываете cancel (true) или cancel (false), зависит от ваших потребностей. не


private class MyTask extends AsyncTask<String, Void, String> 
{  
    @Override 
    protected NewsItem doInBackground(String... params) 
    { 
     try 
     { 
      URL url = new URL("http://www.example.com/"); 
     } 
     catch (MalformedURLException e) 
     { 
      cancel(false/true); 
     } 

     // Other code here... 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    {    
     // Perform successful post processing here... 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
     // Perform error post processing here... 
    } 
} 
+0

Этот метод работает только в том случае, если у нас есть один тип исключения. В моем полном коде есть несколько вещей, которые могут пойти не так, и с ними нужно обращаться по-разному. – Leo

+0

Почему? Вы можете добавить в try-clause столько класс catch, сколько хотите. В каждом выводе вы можете вызвать метод отмены. Вы также можете поймать (исключение e), которое ловит все типы исключений. Я правильно понял, Лео? Однако целесообразно ли отменять отмену() при исключении Exceptions или есть ли другой способ обработки исключений? – OneWorld

+0

Метод отмены() обработки ошибки очень близок к тому, что на самом деле происходит. Ваша обработка была отменена из-за ошибки. Вы все еще можете сохранить некоторое состояние в ASyncTask, которое может быть прочитано потоком пользовательского интерфейса, чтобы получить дополнительную информацию о том, что произошло. – DukeMe