안드로이드 초보입니다.. 널포인트 오류좀 잡아주세요 ㅠㅠ

조회수 1697회

public class MainActivity extends AppCompatActivity { private final static int DEVICES_DIALOG = 1; private final static int ERROR_DIALOG = 2; public static Context mContext; public static AppCompatActivity activity;

TextView myLabel, mRecv;
EditText myTextbox;
static BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button sendButton = (Button)findViewById(R.id.send);

    myLabel = (TextView)findViewById(R.id.label);
    myTextbox = (EditText)findViewById(R.id.entry);
    mRecv = (TextView)findViewById(R.id.recv);
    mContext = this;
    activity=this;
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    if (mBluetoothAdapter == null)
    {
        ErrorDialog("This device is not implement Bluetooth.");
        return;
    }

    if (!mBluetoothAdapter.isEnabled())
    {
        ErrorDialog("This device is disabled Bluetooth.");
        return;
    }
    else
        DeviceDialog();

    sendButton.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            try
            {
                sendData();
            }
            catch (IOException ex) { }
        }
    });
}

static public Set<BluetoothDevice> getPairedDevices() 
{
    return mBluetoothAdapter.getBondedDevices();
}

@Override
public void onBackPressed() {
    doClose();
    super.onBackPressed();
}

public void doClose() {
    workerThread.interrupt();
    new CloseTask().execute();
}


public void doConnect(BluetoothDevice device) {
    mmDevice = device;
    String uniqueID = UUID.randomUUID().toString();
    UUID uuid = UUID.fromString(uniqueID);

    try {
        mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
        mBluetoothAdapter.cancelDiscovery();
        new ConnectTask().execute();
    } catch (IOException e) {
        Log.e("", e.toString(), e);
        ErrorDialog("doConnect "+e.toString());
    }
}

private class ConnectTask extends AsyncTask<Void, Void, Object> {
    @Override
    protected void onPreExecute() {

    }

    @Override
    protected Object doInBackground(Void... params) {
        try {

            mmSocket.connect();
            mmOutputStream = mmSocket.getOutputStream();
            mmInputStream = mmSocket.getInputStream();
            beginListenForData();

        } catch (Throwable t) {
            Log.e( "", "connect? "+ t.getMessage() );
            doClose();
            return t;
        }
        return null;
    }


    @Override
    protected void onPostExecute(Object result) {

        myLabel.setText("Bluetooth Opened");
        if (result instanceof Throwable)
        {
            Log.d("","ConnectTask "+result.toString() );
            ErrorDialog("ConnectTask "+result.toString());

        }
    }
}
private class CloseTask extends AsyncTask<Void, Void, Object> {
    @Override
    protected Object doInBackground(Void... params) {
        try {
            try{mmOutputStream.close();}catch(Throwable t){/*ignore*/}
            try{mmInputStream.close();}catch(Throwable t){/*ignore*/}
            mmSocket.close();
        } catch (Throwable t) {
            return t;
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object result) {
        if (result instanceof Throwable) {
            Log.e("",result.toString(),(Throwable)result);
            ErrorDialog(result.toString());
        }
    }
}



public void DeviceDialog()
{
    if (activity.isFinishing()) return;

    FragmentManager fm = MainActivity.this.getSupportFragmentManager();
    MyDialogFragment alertDialog = MyDialogFragment.newInstance(DEVICES_DIALOG, "");
    alertDialog.show(fm, "");
}



public void ErrorDialog(String text)
{
    if (activity.isFinishing()) return;

    FragmentManager fm = MainActivity.this.getSupportFragmentManager();
    MyDialogFragment alertDialog = MyDialogFragment.newInstance(ERROR_DIALOG, text);
    alertDialog.show(fm, "");
}


void beginListenForData()
{
    final Handler handler = new Handler(Looper.getMainLooper());

    stopWorker = false;
    readBufferPosition = 0;
    readBuffer = new byte[1024];
    workerThread = new Thread(new Runnable()
    {
        public void run()
        {
            while(!Thread.currentThread().isInterrupted() && !stopWorker)
            {
                try
                {
                    int bytesAvailable = mmInputStream.available();
                    if(bytesAvailable > 0)
                    {
                        byte[] packetBytes = new byte[bytesAvailable];
                        mmInputStream.read(packetBytes);
                        for(int i=0;i<bytesAvailable;i++)
                        {
                            byte b = packetBytes[i];
                            if(b == '\n')
                            {
                                byte[] encodedBytes = new byte[readBufferPosition];
                                System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                                final String data = new String(encodedBytes, "US-ASCII");

                                readBufferPosition = 0;

                                handler.post(new Runnable()
                                {
                                    public void run()
                                    {
                                        mRecv.setText(data);
                                    }
                                });
                            }
                            else
                            {
                                readBuffer[readBufferPosition++] = b;
                            }
                        }
                    }
                }
                catch (IOException ex)
                {
                    stopWorker = true;
                }
            }
        }
    });

    workerThread.start();
}

void sendData() throws IOException
{
    String msg = myTextbox.getText().toString();
    if ( msg.length() == 0 ) return;

    msg += "\n";
    Log.d(msg, msg);
    mmOutputStream.write(msg.getBytes());
    myLabel.setText("Data Sent");
    myTextbox.setText(" ");
}

}

다음은 에러로그 입니다

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3

Process: com.example.hwang.easydoorlock, PID: 11604
java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:300)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:841)

 Caused by: java.lang.NullPointerException
    at com.example.hwang.easydoorlock.MainActivity.doClose(MainActivity.java:104)
    at com.example.hwang.easydoorlock.MainActivity$ConnectTask.doInBackground(MainActivity.java:141)
    at com.example.hwang.easydoorlock.MainActivity$ConnectTask.doInBackground(MainActivity.java:124)
    at android.os.AsyncTask$2.call(AsyncTask.java:288)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:841) 

I/Process: Sending signal. PID: 11604 SIG: 9 W/IInputConnectionWrapper: showStatusIcon on inactive InputConnection Application terminated.

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

1 답변

  • public void doClose() {
        workerThread.interrupt();
        new CloseTask().execute();
    }
    

    로그 상으로는 workerThread 가 null 인 상태에서 NullPointerException 이 발생한 것으로 보이네요.

    @Override
        protected Object doInBackground(Void... params) {
            try {
    
                mmSocket.connect();
                mmOutputStream = mmSocket.getOutputStream();
                mmInputStream = mmSocket.getInputStream();
                beginListenForData();
    
            } catch (Throwable t) {
                Log.e( "", "connect? "+ t.getMessage() );
                doClose();
                return t;
            }
            return null;
        }
    

    위 코드에서 beginListenForData() 가 호출 되기 전 예외가 발생하여 catch block 이 실행 되고, 아직 workerThread 객체가 생성 되기 전에 doClose() 에서 workerThread 를 참조 하면서 문제가 발생 하는 것 같습니다.

    CloseTask 는 문제가 없다면 doClose() 를 아래와 같이 처리 해주면 될 것 같네요.

    public void doClose() {
        if(workerThread !=null) {
            workerThread.interrupt();
        }
        new CloseTask().execute();
    }
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 감사합니다. 널포인트 오류가 또 뜨는데 도와주실수 있나요..? 로그 댓글로 달겠습니다. 알 수 없는 사용자 2018.12.4 21:42
    • java.lang.NullPointerException at com.example.hwang.easydoorlock.MainActivity.sendData(MainActivity.java:266) at com.example.hwang.easydoorlock.MainActivity$1.onClick(MainActivity.java:78) at android.view.View.performClick(View.java:4442) at android.view.View$PerformClick.run(View.java:18471) 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:5103) 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:790) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606) at dalvik.system.NativeStart.main(Native Method) I/Process: Sending signal. PID: 21511 SIG: 9 알 수 없는 사용자 2018.12.4 21:42
    • sendData() 에서 NullPointerException 이 발생하고 있습니다. 메소드 내부에서 null 이 될만한 값을 먼저 찾아보세요. myLabel, myTextBox 는 이미 onCreate() 에서 생성 되었고, (해당 객체가 문제였다면 애초에 onCreate() 에서 문제가 발생했겠죠) 또한 EditText.getText().toString() 에선 NullPointerException 이 발생하지 않습니다. 그렇다면 가장 의심되는 부분은 mmOutputStream 입니다. 해당 변수가 null 이 될 여지에 대해 분석해보시면 될 것 같네요 알 수 없는 사용자 2018.12.4 21:55
    • 해결했습니다!! 감사합니다!! 알 수 없는 사용자 2018.12.4 22:19

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

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

(ಠ_ಠ)
(ಠ‿ಠ)