해당 에러는 허니컴 이후부터 네트워크 관련 작업을 진행할 때 발생할 수 있습니다. 메인 Thread 에서 발생하는 에러로 네트워크를 이용해 데이터를 받기 위해서는 별개의 Thread 가 필요합니다. 그렇지 않으면 Stream 객체를 통해 데이터를 읽어 오는 과정에서 android.os.NetworkOnMainThreadException 에러가 나게 됩니다. 네트워크 처리를 잘 못하게 되면 메인 Thread 가 멈출 수 있으므로 강제로 분리해서 구현하도록 만든 것 같습니다.
▼ 데이터를 읽어 오는 InputStreamReader 에서 Exception 이 발생한 것입니다. 네트워크 특성상 가져오는 데이터 양이 정해져 있지 않기 때문에 Thread 를 별도로 돌려야 합니다. 그렇지 않으면 데이터를 가져오는 동안 프로그램이 멈춰 있겠죠.

▼ 네트워크를 통해서 데이터를 가져오는 소스는 다음과 같습니다. 여기에 에러가 나지 않도록 Thread 를 추가하겠습니다. 데이터를 가져오는 getNaverHtml() 함수가 Thread 안에서 실행을 해야겠죠.
import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class NetworkActivity extends Activity { private TextView edtHtml; final int CONN_TIME = 5000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_network); String naverHtml = getNaverHtml(); edtHtml = (TextView)this.findViewById(R.id.edtHtml); edtHtml.setText(naverHtml); } private String getNaverHtml(){ String naverHtml = ""; HttpURLConnection con = null; InputStreamReader isr = null; BufferedReader br = null; try{ URL url = new URL("http://www.naver.com"); con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(CONN_TIME); con.setReadTimeout(CONN_TIME); isr = new InputStreamReader(con.getInputStream()); br = new BufferedReader(isr); String str = null; while ((str = br.readLine()) != null) { naverHtml += str + "\n"; } }catch(Exception e){ e.printStackTrace(); }finally{ if(con != null){ try{con.disconnect();}catch(Exception e){} } if(isr != null){ try{isr.close();}catch(Exception e){} } if(br != null){ try{br.close();}catch(Exception e){} } } return naverHtml; } }
▼ 아래 소스처럼 getNaverHtml() 함수를 Thread 의 run() 함수 안에 넣고 실행합니다. 가져온 데이터는 메인 Thread 인 화면에 데이터를 전달하기 위해서 Handler 을 사용합니다.
new Thread() { public void run() { String naverHtml = getNaverHtml(); Bundle bun = new Bundle(); bun.putString("HTML_DATA", naverHtml); Message msg = handler.obtainMessage(); msg.setData(bun); handler.sendMessage(msg); } }.start();
▼ 데이터를 화면에 표시하는 Handler 소스는 다음과 같습니다. Thread 로부터 전달 받은 html 데이터를 EditText 추가합니다.
Handler handler = new Handler() { public void handleMessage(Message msg) { Bundle bun = msg.getData(); String naverHtml = bun.getString("HTML_DATA"); edtHtml.setText(naverHtml); } };
▼ 전체 소스는 다음과 같습니다.
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class NetworkActivity extends Activity { private TextView edtHtml; final int CONN_TIME = 5000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_network); String naverHtml = getNaverHtml(); edtHtml = (TextView)this.findViewById(R.id.edtHtml); //edtHtml.setText(naverHtml); new Thread() { public void run() { String naverHtml = getNaverHtml(); Bundle bun = new Bundle(); bun.putString("HTML_DATA", naverHtml); Message msg = handler.obtainMessage(); msg.setData(bun); handler.sendMessage(msg); } }.start(); } Handler handler = new Handler() { public void handleMessage(Message msg) { Bundle bun = msg.getData(); String naverHtml = bun.getString("HTML_DATA"); edtHtml.setText(naverHtml); } }; private String getNaverHtml(){ String naverHtml = ""; HttpURLConnection con = null; InputStreamReader isr = null; BufferedReader br = null; try{ URL url = new URL("http://www.naver.com"); con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(CONN_TIME); con.setReadTimeout(CONN_TIME); isr = new InputStreamReader(con.getInputStream()); br = new BufferedReader(isr); String str = null; while ((str = br.readLine()) != null) { naverHtml += str + "\n"; } }catch(Exception e){ e.printStackTrace(); }finally{ if(con != null){ try{con.disconnect();}catch(Exception e){} } if(isr != null){ try{isr.close();}catch(Exception e){} } if(br != null){ try{br.close();}catch(Exception e){} } } return naverHtml; } }
※ 아래는 참고하면 좋을 만한 글들의 링크를 모아둔 것입니다. ※ ▶ 스마트폰 안드로이드 개발을 위한 개발자 모드 켜고 끄는 방법 ▶ 이클립스(Eclipse) 안드로이드 개발도구 ADT 설치하기 ▶ 안드로이드 스튜디오 개발 문서 API 참고하는 방법 ▶ 안드로이드 Android 앱 배포를 위한 개발자 등록하기 ▶ 안드로이드 개발 Intent 이용한 전화 걸기 |
'안드로이드 개발' 카테고리의 다른 글
안드로이드 개발 에러 have you declared this activity in your AndroidManifest.xml ? (0) | 2023.01.14 |
---|---|
안드로이드 개발 에뮬레이터 카메라 QR 스캔하기 (1) | 2022.11.15 |
안드로이드(Android) 레이아웃(Layout) gravity, layout_gravity 차이점을 알아보자. (6) | 2022.11.14 |
안드로이드 개발 이미지 추가하고 화면에 출력하는 방법 (0) | 2022.10.23 |
안드로이드(Android) ImageView 에 이미지 회전(Image rotate) 시켜서 세팅하는 방법 (1) | 2022.07.31 |
안드로이드 개발 No cached version available for offline mode 에러 해결하기 (0) | 2022.07.19 |
안드로이드 개발 Fragment 생명 주기는 어떻게 되는가? (0) | 2022.06.20 |
[Android] 안드로이드 인터넷 이미지 다운로드 해서 ImageView 표현하기 (2) | 2020.07.12 |