2012-03-09 1 views
1

У меня есть приложение для Android, которое вытягивает xml с сервера.Как бороться с Java AssertionError (java.lang.SocketException)?

public class FeedParser { 

    private final URL mURL; 

    public FeedParser(String feedUrl) { 
     try { 
      mURL = new URL(feedUrl); 
     } catch (MalformedURLException e) { 
      throw new RuntimeException(); 
     } 
    } 

    private InputStream getInputStream() throws IOException { 
     return mURL.openConnection().getInputStream(); 
    } 

    public FeedItem parseFeed() { 
     // SAX stuff here 

     try { 
      Xml.parse(getInputStream(), Xml.Encoding.UTF_8, 
        root.getContentHandler()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return result; 
    } 
} 

Иногда, когда XML.parse (...) выполняет, я получаю исключение:

AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground() 
AndroidRuntime: at android.os.AsyncTask$3.done(AsyncTask.java:200) 
AndroidRuntime: at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
AndroidRuntime: at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
AndroidRuntime: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
AndroidRuntime: at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
AndroidRuntime: at java.lang.Thread.run(Thread.java:1019) 
AndroidRuntime: Caused by: java.lang.AssertionError: java.net.SocketException: Connection reset by peer 
AndroidRuntime: at android.util.Xml.parse(Xml.java:89) 
AndroidRuntime: at com.packagename.FeedParser.parseFeed(FeedParser.java:60) 
AndroidRuntime: at com.packagename.UpdateService$FeedLookupTask.doInBackground(UpdateService.java:84) 
AndroidRuntime: at com.packagename.UpdateService$FeedLookupTask.doInBackground(UpdateService.java:1) 
AndroidRuntime: at android.os.AsyncTask$2.call(AsyncTask.java:185) 
AndroidRuntime: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
AndroidRuntime: ... 4 more 
AndroidRuntime: Caused by: java.net.SocketException: Connection reset by peer 
AndroidRuntime: at org.apache.harmony.luni.platform.OSNetworkSystem.read(Native Method) 
AndroidRuntime: at dalvik.system.BlockGuard$WrappedNetworkSystem.read(BlockGuard.java:273) 
AndroidRuntime: at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:458) 
AndroidRuntime: at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:85) 
AndroidRuntime: at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:65) 
AndroidRuntime: at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:140) 
AndroidRuntime: at java.io.BufferedInputStream.read(BufferedInputStream.java:225) 
AndroidRuntime: at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.readLine(HttpURLConnectionImpl.java:660) 
AndroidRuntime: at org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream.readChunkSize(ChunkedInputStream.java:77) 
AndroidRuntime: at org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream.read(ChunkedInputStream.java:45) 
AndroidRuntime: at java.io.InputStream.read(InputStream.java:157) 
AndroidRuntime: at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:516) 
AndroidRuntime: at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:479) 
AndroidRuntime: at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:318) 
AndroidRuntime: at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:275) 

Как обрабатывать такую ​​ошибку?

EDIT Зная, что ошибки ловли - это плохой стиль программирования, я ищу более элегантное решение.

+1

повторить синтаксический анализ/выборка?В принципе, исключение не плохое, это просто показывает, что что-то пошло не так. Так что просто подумайте о том, как повторить попытку и сделать это (не повторяйте навсегда! Сделайте счетчик повторов, который ограничивает его). – WarrenFaith

+0

Я слышал, что это плохая идея поймать Ошибки. Для этого мне нужно написать catch (Throwable)? –

+0

Нет, нет. catch (AssertionError e). –

ответ

1

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

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

Другая возможность, в зависимости от размера вашего xml, состоит в том, чтобы прочитать ее в строковый буфер, а затем проанализировать. С большими данными это уменьшает вероятность перезагрузки, так как ваши серверные соединения будут намного короче, чем когда вы будете разбираться по мере того, как вы идете. Я думаю здесь о сценарии, когда окно tcp закрывается в течение длительного времени, пока вы разбираетесь, и в конце концов другая сторона решает, что вы мертвы, и сбрасывает соединение.

+1

@JarleHansen Почему это плохая идея ловить ошибки? Если это исключение, с которым вы можете справиться, почему бы не поймать его, повторите попытку x раз и повторите бросок, если он все еще не работает? – ebaxt

+0

@JarleHansen Конечно, это «серьезная проблема», что удаленный клиент зависает на клиенте, но, возможно, сервер был занят именно тогда? Это в высшей степени хорошая идея поймать ошибку в этом случае и повторить разумное количество раз. – alphazero

+0

Вы, ребята, правы, похоже, что это случай, когда вам действительно нужно поймать AssertionError. Моя ошибка по этому вопросу. –

0

AssertionError содержит стандартный способ предупредить, что неверно утверждается, что программист ошибочен.

Поэтому, когда хорошо использовать, они говорят, «есть ошибка кодирования здесь» (потому что вы бросаете их в местах, которые заявлены в unreacheable), и это является причиной того, почему AssertionError является (распространяется) Error и не Exception: они сообщают о невосстановимом (во время выполнения) сбое (поскольку вы должны перекодировать алгоритм).

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

Таким образом, отвечая на ваш вопрос, вы можете справиться с этим, чтобы способами:

  • Если код бросает ошибку вами (я сомневаюсь, что это так дано на ваш вопрос, но в будущем должно быть): Просмотрите и исправьте свой алгоритм.
  • Если из библиотеки третьей стороной: Зарегистрировать ошибку в его автору (или попытаться решить ее самостоятельно)

Но вы не должны обрабатывать его в вашем коде.

В качестве дополнительного примечания: ваш случай заставляет меня сомневаться, если android.util.Xml.parse() правильно его использует. Очень странно, что AssertionError, имеющий дело (будучи построен из другого Throwable), так что это еще один вариант, чтобы иметь в виду: может быть, эта библиотека не очень хорошо реализовано ...

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