해당 에러는 허니컴 이후부터 네트워크 관련 작업을 진행할 때 발생할 수 있습니다. 메인 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 |