2014년 2월 27일 목요일

Android NetworkOnMainThreadException

Android 메인 Thread에서 라이프사이클과 다양한 Callback을 처리하다 보니 시간이 오래걸리는 작업을 하게 되면 응답속도가 느려져 사용자가 불편해 한다. 그래서 Honeycomb 버전 부터 어플리케이션 응답속도을 보장하기 위해 많은 메인 Thread내에서 시간이 오래걸리는 네트워크 작업이나 UI을 핸들링 하지 못하게 하였다. "NetworkOnMainThreadException"은 메인 Thread내에서 네트워크 작업을 진행하려할때 발생한다.
그러면 어떻게 해결하나? 해결 방법은 2가지가 있는데 AsyncTask을 이용하는 방법과 StrictMode을 활용한 방식이 있다.

AsyncTask 사용 예
너무들 잘 알려진 AsyncTask입니다.
public class AsyncTaskMainActivity extends Activity {
private Button bStartTask = null;
private Button bInitState = null;
private TextView tStateView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.async_task_main);
bInitState = (Button)findViewById(R.id.bInit);
bStartTask = (Button)findViewById(R.id.bTask);
tStateView = (TextView)findViewById(R.id.tState);
bStartTask.setOnClickListener(new TaskOnClickListener());
bInitState.setOnClickListener(new TaskOnClickListener());
}

public class TaskOnClickListener implements android.view.View.OnClickListener {

public void onClick(View v) {
if (v.getId() == R.id.bInit) {
} else if (v.getId() == R.id.bTask) {
new BackTask().execute(tStateView);
}
}
}
public class BackTask extends AsyncTask<TextView, String, String> {
TextView tState = null;
@Override
protected void onProgressUpdate(String... values) {
tState.setText(values[0]);
}

@Override
protected String doInBackground(TextView... args) {
tState = args[0];
try {
publishProgress("기다리고 있습니다.");
Thread.sleep(3000);
} catch (InterruptedException e) {
publishProgress(e.getMessage());
}
return "Task 완료";
}

@Override
protected void onPostExecute(String result) {
tState.setText(result);
}

}
}

AsyncTask의 odInBackgroud내에서는 직접적으로 UI을 핸들링 할 수 없습니다. 처리중에 UI을 변경하려면 onProgressUpdate을 사용하고 완료후에는 onPostExecute을 사용하면됩니다.
예제를 네트워크 관련해서 만들려고 했는데 코드가 길어져서 UI로 했습니다. 중요한것은 개념이니깐요!

StrictMode 사용 예
이 방법은 허니컴 이상의 버전에서의 Thread정책을 모두 기존처럼 사용하겠다고 선언하는 방식으로 권장하지 않습니다.

Activity의 onCreate에 다음 코드를 넣습니다.
if(android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}


댓글 없음:

댓글 쓰기

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...