본문 바로가기

안드로이드 개발 팁/일반

android.os.NetworkOnMainThreadException이 발생할 경우


안드로이드 4.0

3.0 (침묵님 지적 감사합니다) 이후 버전부터 발생하는 오류로 추정되며, UI쓰레드(메인 쓰레드)에서 네트워크 통신을 사용하여 메인 쓰레드를 블록(Block)하게 될 경우 발생되는 오류입니다. 아래는 오류 로그의 예시입니다.

11-07 15:14:18.816: E/AndroidRuntime(15427): FATAL EXCEPTION: main

11-07 15:14:18.816: E/AndroidRuntime(15427): android.os.NetworkOnMainThreadException

11-07 15:14:18.816: E/AndroidRuntime(15427): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)

11-07 15:14:18.816: E/AndroidRuntime(15427): at java.net.InetAddress.lookupHostByName(InetAddress.java:406)

11-07 15:14:18.816: E/AndroidRuntime(15427): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:246)

11-07 15:14:18.816: E/AndroidRuntime(15427): at java.net.InetAddress.getAllByName(InetAddress.java:224)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)

11-07 15:14:18.816: E/AndroidRuntime(15427): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)

11-07 15:14:18.816: E/AndroidRuntime(15427): at java.net.URL.openStream(URL.java:461)



이전 버전까지는 UI쓰레드에서 네트워크 작업을 처리해도 별도로 오류가 발생하지는 않았습니다. 물론 네트워크 상태가 좋지 않으면 메인 쓰레드가 블록되어 애플리케이션이 멈춘 것처럼 보이기에 잘 쓰지는 않았지요. 하지만 일부 애플리케이션은 그냥 메인 쓰레드에서 네트워크 작업을 처리해서 사용성에 안좋은 영향을 끼친 것은 사실입니다.

아마 안드로이드 4.0 이후부터는 이와 같이 사용성에 영향을 주는 요소를 미연에 차단하려나 봅니다.
그렇다면.. 이 문제는 어떻게 해결해야하느냐구요?? 간단합니다. AsyncTask나 Thread를 사용하여 UI쓰레드에 영향을 주지 않도록 작성하면 됩니다. :) 조금 귀찮기는 하더라도, 네트워크 작업은 별도의 스레드에서 처리되도록 구현하는 것이 훨씬 좋으므로 이 기회에 AsyncTask를 사용하는 습관을 들이는 것도 나쁘지는 않을 듯 합니다. :)