본문 바로가기
Development/Android

[안드로이드]HttpURLConnection/getOutputStream() 에러

by 메정 2020. 2. 18.

먼저 현재 안드로이드 어플 - phpmyadmin서버와 데이터베이스를 연동하여 저장하고 있다.

첫 번째, 회원 정보를 저장 할 때에는 jsonObject에 넣어서 저장을 했었는데,

같은 방법으로 다른 액티비티에서 데이터에 저장하려하니 어려워서 다른 방법을 찾았다.

어떤 방법이냐 하면! 

outStream을 이용하여 서버에서 읽은 값을 저장하는 것! 이 분 블로그를 보고 참고하여 구현하였다. 

그런데 ! 내 코드 중 OutputStream outputStream = conn.getOutputStream(); 이 부분에서 오류가 난 것!

로그캣을 보니 이 오류는 NetworkOnMainThreadException이라는 사실을 알아낼 수 있었고! 이를 해결하기 위해 원인을 찾아보았다.


알아보니 다음과 같았다! (틀릴 수도 있다. 틀리면 댓글로 틀렸다고 말해주길 바란다. 배워가는 단계이기 때문!)

안드로이드 앱은 일반적으로 프로세스 하나 위에 여러 멀티 프로세스가 돌고 있는 형태이다!

메인스레드(UI스레드. 같은 말이라 한다. ) 가 아닌 작업스레드(백그라운드 스레드)에서 UI를 변경하려고 하면 이 예외가 발생한다.

일반적으로 onCreate()에서 실행되는 메소드들은 다 메인스레드에서 동작한다고 볼 수 있다.  이미지를 다운 받고, 네트워크 작업을 처리하는 것과 같이 부가적인 작업은 작업스레드에서 해야 한다! 

- 여기서 나의 문제상황 : 메인 스레드에서 내부클래스로 만들어 놓은 네트워크 작업(HttpURLConnection을 이용한)을 객체로 생성하여 시도하려 함. 오류 발생.

이런 경우 1. 스레드를 이용하여 처리하기와 2. AnsycTask를 이용하기의 두가지 방법이 있다.

1을 이용하기 위해서 무명객체(new Thread().start;) 를 시도해 보았지만, 실패하였다.

그래서 2를 이용하여 진행했더니 됐다! 

class NetWorkAsynsTask extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... arg0){
// public String PHPtestCART(String userId, String list) {
try {
String userId = arg0[0];
String list = arg0[1];
String postData = //전송 데이터 https://twinw.tistory.com/29
String link = //php서버 주소.
URL url = new URL(link);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestMethod("POST");
conn.setConnectTimeout(5000);
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStream outputStream = conn.getOutputStream(); //******오류 발생. 해결하기위해 해당 클래스 AsyncTask 상속하도록 수정
outputStream.write(postData.getBytes("UTF-8"));
outputStream.flush();
outputStream.close();
String result = readStream(conn.getInputStream());
conn.disconnect();
return result; // success : 1, fail : -1
}
catch (Exception e) {
Log.i("PHPRequestCART", "request was failed.");
e.printStackTrace();
return null;
}
}

이런 식으로 아까 오류가 발생했던 코드 부분의 클래스를 AsyncTask를 이용하여 상속하도록 하였고, 호출 할 때에는 다음과 같이 했더니 db에 잘 들어갔다! ㅎㅛㅎ 행복.

AsyncTask<String, String, String> result = new NetWorkAsynsTask().execute(userId, list);


댓글