1

私はJavaで書かれたAndroidアプリを持っています。

アプリは基本的に、アプリメッセージを送信するデバイスに接続します。アプリは、各メッセージを処理する前に、メッセージが着信するのを待ってから報告します。

ConnectionクラスとListenerクラスがあります。

Connectionクラスは、デバイスから着信するメッセージをリッスンするためにListenerクラスを設定するコンストラクターを介して開始されます。

メッセージが着信すると、リスナーはそのメッセージをConnectionクラスのメソッドreportMessage()に送信します。ここでメッセージが処理されます。

Listenerクラスは別のスレッドにあります。

コードを以下に示します。

public class Connection 
{
    private String response;
    private String newResponse;

    private DataInputStream reader;

    private DataOutputStream writer; 

    private Socket socket;

    private boolean keepListening;

    private Listener listener;

    public Connection (String _ipAddress, int portNumber)
    {
        newResponse = "";

        try 
        {
            socket = new Socket(_ipAddress, _port);   //Connect to the server and its socket

            writer = new DataOutputStream(socket.getOutputStream()); //Connect to the server to receive and send messages

            reader = new DataInputStream(socket.getInputStream());

            listener = new Listener(reader, this); //Create a new listener for the client

            new Thread(listener).start(); //Set the listener off running
        } 
        catch (Exception e) 
        {
            ...
        } 
    }

    public synchronized void reportMessage(String message)
    {
        try
        {
            if("".equals(newResponse))
            {
                newResponse = new String();
            }

            newResponse = newResponse + message;

            System.out.println("Message Received: " + newResponse);

            processMessage(); //Process the message
        }
        catch (Exception e)
        {
            response = e.getCause().toString();
        }
    }
}

public class Listener implements Runnable 
{
    private DataInputStream reader = null;

    private boolean keepListening;

    private String serverMessage;

    private Connection connection;

    public Listener (DataInputStream inFromServer, Connection connection)
    {
        reader = inFromServer;
                               //Get the client connection's message transfer
        keepListening = true;

        this.connection = connection;
    }

    public void run()
    {
        while (keepListening)
        {
            try
            {
                if (reader.available() > 0)
                {
                    byte[] readInData = new byte[reader.available()];  //Initialise the array

                    reader.read (readInData);  //Read in the data

                    serverMessage = Utils.byteToString(readInData);

                    connection.reportMessage(serverMessage);   //Report the message
                }
            }
            catch (IOException e)
            {
                System.out.println("Error reading." + e.getLocalizedMessage().toString());

                keepListening = false;
            }

            keepListening = connection.getKeepListening();
        }
    }
}

これはしばらくの間はうまく機能しますが、プログラムをクラッシュさせるエラーが表示されることがあります。

デバッグモードで実行すると、ConnectionクラスのreportMessage()の最初の行にNullPointerExceptionがスローされます。

プログラムは、System.out.printlnであろうと実際のコードの行であろうと、最初の行が何であれ中断されます。

そして、エラーは試行錯誤によって捕らえられません。プログラムがクラッシュし、try and catchで発生したとしても、エラーの処理は行われません。

これにより、reportMessage()メソッドの何によってもエラーがスローされていないと思います。この場合、おそらくエラーがリスナークラス.run()でスローされています。

ただし、すべてのチェックを実行しようとしたため、 NullPointerExceptionがどこからスローされるかがわかりません。スローされると、メッセージが送信されたときにスローされます。

デバッガーは「例外スタックトレースは利用できません」と言います。

LogCatによると:

  08-21 10:35:57.894: E/AndroidRuntime(1118): FATAL EXCEPTION: Thread-12
  08-21 10:35:57.894: E/AndroidRuntime(1118): java.lang.NullPointerException
  08-21 10:35:57.894: E/AndroidRuntime(1118):atCom.que.wifiaudio.Connection.reportMessage(Connection.java:339)
  08-21 10:35:57.894: E/AndroidRuntime(1118):   at com.que.wifiaudio.Listener.reportIncomingMessage(Listener.java:93)
  08-21 10:35:57.894: E/AndroidRuntime(1118):   at com.que.wifiaudio.Listener.run(Listener.java:67)

  08-21 10:35:57.894: E/AndroidRuntime(1118):   at java.lang.Thread.run(Thread.java:1102)

誰か助けてもらえますか?

NullPointerExceptionをスローしているものと、それを停止する方法を知る必要があります。

編集:多くの助けのおかげで、それは私が捕らえ、原因を取得しようとしている例外であることがわかりました。その原因はnullです。それがどこから来ているのかまだ解明しようとしています!

4

5 に答える 5

1
  if((newResponse==null) || ("".equals(newResponse))

または、素晴らしいグアバを使用してください。

  if(Strings.isNullOrEmpty(newResponse))
于 2012-08-22T09:32:51.407 に答える
1

私の推測では、例外がprocessMessageでスローされ、その下のキャッチでキャッチされますが、getCauseはnullです。

1/例外を処理する前にログに記録してみてください

2 / processMessageを調べてください、例外がスローされるはずです。

于 2012-08-22T09:52:28.727 に答える
0

messageまたは、コンパイラnewResponseに変換されるため、nullになる可能性があります。message.toString()newResponse.toString()

nullチェックの条件を追加します:

if(message != null && newResponse!=null) {
   newResponse = newResponse + message;
} else {
   // throw exception ...
}
于 2012-08-22T09:31:00.313 に答える
0

それ以外の:

if("".equals(newResponse))

これを使って:

if(newResponse==null)

null空の文字列はオブジェクトと同じではありません。newResonseしたがって、がの場合null、適切なStringオブジェクトで初期化されず、NPEで終了します。

于 2012-08-22T09:31:41.910 に答える
0

私が見ていることの1つは、reportMessage()で、newResponseが空の文字列であるかどうかをチェックしていることです。ただし、以前に初期化したことがないため、nullである可能性があります。おそらくあなたが欲しいのは

if(newResponse == null) {
    newResponse = new String();
}
于 2012-08-22T09:36:43.437 に答える