안드로이드에서 Network를 이용한 TCP/IP 통신을 구현함에 있어 다음과 같은 에러가 발생했습니다
android.os.NetworkOnMainThreadException
해당 에러의 발생 원인은 Network API를 MainActivity에서 직접 호출했을 경우인데
MainActivity에서 Network관련 작업을 직접 실행할 경우 MainThread가 멈추는 현상이
발생할 수 있기 때문에 Android OS에서는 해당 에러 문구를 출력하게 됩니다.
즉 해당 에러는 MainThread에서 Network를 호출했다는게 문제가 된다는 것인데
간단하게 해결할 수 있는 방법은 MainThread가 아닌 Sub Thread에서 해당 작업을 하거나
Background 작업에서 Network 관련 기능을 실행하면 됩니다
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
socket.connect(new InetSocketAddress("1.1.1.1",1234));
is = socket.getInputStream();
os = socket.getOutputStream();
}
먼저 해당 에러는 위 코드처럼 MainActivity의 onCreate에서 직접 Socket을 connect 했을 때
발생하는 것을 확인할 수 있는데 MainActivity의 onCreate는 MainThread이기 때문입니다
즉 이 문제를 해결하기 위해 간단하게 Thread를 통해 구현이 가능합니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(()->{
socket.connect(new InetSocketAddress("1.1.1.1",1234));
is = socket.getInputStream();
os = socket.getOutputStream();
}).start();
}
위 방법은 별도의 Thread를 선언하지 않고 구현하는 방법으로
new Thread를 통해 Socket Connect 작업을 sub Thread로 넘겼기 때문에
MainThread와는 별도로 동작하고 해당 에러 또한 해결이 가능합니다.
여기서 많은분들이 혼동하시는 부분은 Handler를 이용해서 처리해도 되냐고 물어보시는데
Handler작업은 엄밀히 말해서 MainThread에서 동작하기 때문에 sub Thread와는 다른 개념입니다.
먼저 위 코드에서 new Thread를 통해 구현이 되면 코드가 약간 지저분한 느낌이 있습니다.
나중에 코드를 읽을때에도 정확히 무슨 부분인지 명시적으로 파악이 되지 않기 때문에
좀 더 깔끔한 코드를 위해서는 다음과 같은 코드가 좋다 생각됩니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NetWorkConnect net = new NetWorkConnect();
net.start();
}
class NetWorkConnect extends Thread {
@Override
public void run() {
socket.connect(new InetSocketAddress("1.1.1.1",1234));
is = socket.getInputStream();
os = socket.getOutputStream();
}
}
명시적인 Thread를 정의하고 MainThread에서는 해당 Thread를 호출하는 방식으로 사용하면
이 부분이 NetworkConnct를 실행하는 부분이구나라고 한 번에 파악이 되기 때문에
되도록이면 코드에도 어느 정도 정리가 필요합니다
'안드로이드' 카테고리의 다른 글
[Android] Only the original thread that created a view hierarchy can touch its views 에러 해결 (2) | 2022.10.27 |
---|---|
[Android] 자바에서 Unsigned 타입 적용하기 (3) | 2022.10.13 |
[Android] Manifest merger failed with multiple errors 해결 (2) | 2022.10.06 |
[Android] ProgressBar 막대 색상 변경 (2) | 2022.09.27 |
[Android] 다이얼로그 뷰바인딩 wrap_content 고정되는 문제 해결 (6) | 2022.09.23 |
댓글