FATAL EXCEPTION:main 오류가 발생합니다

조회수 9267회

소켓통신하는 앱을 작성했습니다 버튼을누르면 editText에 있는 내용을 전송하려고합니다. 소켓이 잘 연결되면 오류가 나지않지만 연결이 안된경우에 버튼을 누르면 앱이 강제 종료 됩니다.

메인액티비티 입니다.

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ConnectException; import java.net.Socket;

import android.app.Activity; import android.os.Bundle;

import android.util.Log;

import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast;

public class socket extends Activity { //메인 activity

Socket socket;  //소켓생성

BufferedReader in;      //서버로부터 온 데이터를 읽는다.
PrintWriter out;        //서버에 데이터를 전송한다.
EditText input;         //xml 요소
Button button;          //xml 요소
TextView output;        //xml 요소
String data;            //소켓 데이터 저장

@Override
protected void onCreate(Bundle savedInstanceState) {   //앱 시작시  초기화설정
    super.onCreate(savedInstanceState);
    setContentView(R.layout.socket_lay);       //레이아웃 로드

    input = (EditText) findViewById(R.id.input); // 글자입력(edit text)
    button = (Button) findViewById(R.id.button); // 전송버튼
    output = (TextView) findViewById(R.id.output); // 수신데이터

    button.setOnClickListener(new OnClickListener() {       //버튼으로 전송하는  부분
        public void onClick(View v) {               //버튼이 클릭되면 소켓에 데이터를 출력한다.

            String data = input.getText().toString(); //글자입력칸에 있는 글자를 String 형태로 받아서 data에 저장
            Log.w("NETWORK", " " + data);
            if (data != null) {     //만약 데이타가 아무것도 입력된 것이 아니라면
                out.println(data);  //data를   stream 형태로 변형하여 전송.  변환내용은 쓰레드에 담겨 있다.
            }
        }
    });

    Thread worker = new Thread() {    //worker 를 Thread 로 생성
        public void run() { //스레드 실행구문

            try {       //소켓을 생성하고 입출력 스트립을 소켓에 연결한다.
                socket = new Socket("192.168.4.1", 8080); //소켓접속
                out = new PrintWriter(socket.getOutputStream(), true); //데이터를 전송시 stream 형태로 변환하여                                                                                                                       //전송한다.
                in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));//데이터 수신시 stream을 받아들인다.

            } catch (IOException e) {   //부가설명 https://code.i-harness.com/ko-kr/q/c9a994
                e.printStackTrace();
                Toast.makeText(com.example.jbts201604.socket_37.socket.this,"연결오류",Toast.LENGTH_SHORT).show();
            }


            try {
                while (true) {
                    data = in.readLine(); // in으로 받은 데이터를 String 형태로 읽어 data 에 저장

                    output.post(new Runnable() {
                        public void run() {
                            output.setText(data); //글자출력칸에 서버가 보낸 메시지를 출력한다.
                        }
                    });
                }
            } catch (Exception e) {
                Toast.makeText(com.example.jbts201604.socket_37.socket.this,"수신오류",Toast.LENGTH_SHORT).show();

            }
        }
    };
    worker.start();  //onResume()에서 실행.
}

@Override
protected void onStop() {  //앱 종료시
    super.onStop();
    try {
        socket.close(); //소켓을 닫는다.
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

logcat내용입니다.

09-05 12:17:40.899 3195-3195/? D/dalvikvm: Not late-enabling CheckJNI (already on) 09-05 12:17:44.769 3195-3195/com.example.jbts201604.socket_37 D/EGL_emulation: eglCreateContext: 0xb7d92fd0: maj 2 min 0 rcv 2 09-05 12:17:44.829 3195-3195/com.example.jbts201604.socket_37 D/EGL_emulation: eglMakeCurrent: 0xb7d92fd0: ver 2 0 09-05 12:17:44.829 3195-3195/com.example.jbts201604.socket_37 E/EGL_emulation: tid 3195: eglSurfaceAttrib(1199): error 0x3009 (EGL_BAD_MATCH) 09-05 12:17:44.829 3195-3195/com.example.jbts201604.socket_37 W/HardwareRenderer: Backbuffer cannot be preserved 09-05 12:17:44.829 3195-3195/com.example.jbts201604.socket_37 D/OpenGLRenderer: Enabling debug mode 0 09-05 12:17:48.479 3195-3195/com.example.jbts201604.socket_37 W/NETWORK:
09-05 12:17:48.479 3195-3195/com.example.jbts201604.socket_37 D/AndroidRuntime: Shutting down VM 09-05 12:17:48.479 3195-3195/com.example.jbts201604.socket_37 W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x9cccfb20) 09-05 12:17:48.479 3195-3195/com.example.jbts201604.socket_37 D/dalvikvm: GC_FOR_ALLOC freed 70K, 4% free 3436K/3576K, paused 2ms, total 2ms 09-05 12:17:48.479 3195-3195/com.example.jbts201604.socket_37 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.jbts201604.socket_37, PID: 3195 java.lang.NullPointerException at com.example.jbts201604.socket_37.socket$1.onClick(socket.java:48) at android.view.View.performClick(View.java:4438) at android.view.View$PerformClick.run(View.java:18422) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method)

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • Android 보안 규칙 강화로 인하여 네트워크, fileio, db 등의 작업은 UI Thread 에서 동작하면 Crash 발생 합니다. 네트워크 관련 작업(소켓 연결 바인딩) 해당 작업을 쓰레드나 핸들러를 이용하여 처리 해보세요. 임재훈 2018.9.6 09:56

2 답변

  • Android 보안 규칙 강화로 인하여 네트워크, fileio, db 등의 작업은 UI Thread 에서 동작하면 Crash 발생 합니다. 네트워크 관련 작업(소켓 연결 바인딩) 해당 작업을 쓰레드나 핸들러를 이용하여 처리 해보세요.

    로그상에는 메인스레드(유아이스레드)에서 소켓작업을 하다가 crash 발생하는 것으로 보이네요.

  • log 를 보면 onClick() 에서 Exception이 발생하고 있습니다.

    String data = input.getText().toString();
    

    여기서 data 는 항상 null 이 아니므로 NullPointerException 이 발생할만한 부분은 out 변수에 있습니다. 따라서 소켓 연결이 되지 않았을 때 PrintWriter 객체가 생성되지 못하여 out 변수에 의한 NullPointerException 이 발생하는 것으로 보입니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)