0

これは、プログラミング中に私に起こった最も奇妙なことです。はい、私はプログラミングのプロではありませんが、学習しながら学んでいます。サーバーと通信するアプリ、メインスレッドのソケット、読み取りは別のクラスとスレッドで行われ、asynctask を使用して別のクラスで書き込みが行われます。

問題は LocationManager です。サーバーと通信し、コマンドの書き込み/読み取りを問題なく行うことができました。LocationManager とそのリスナーを実装しました。

次に、テキストビューを locatinChanged の新しい座標で更新するメソッドの実装に進みました。ここまでは順調ですね。問題は、Eclipse でエミュレーター コントロールを使用して座標を送信すると、アプリが stringOutOfBoundsException でクラッシュしたことです (私は 3 年間プログラムしてきましたが、これを見たことがありません)。私はそれをステップスルーしたコードなどを見ました。スタックトレース、logcat、コンソールなど、考えられるあらゆる場所を読みましたが、どこにも行きませんでした。最終的に次のようなリーダースレッドに移動するまで:

    public class ReaderThread extends Thread {
    public void run() {
        new Thread(new Runnable(){
            public void run(){                  
                try {
                    //Establish a bufferedreader to read from the socket/server.
                    in = new BufferedReader(new InputStreamReader(socket.getInputStream()), 8 * 1024);
            } 
            catch(Exception e) { e.printStackTrace(); }
        
        //As long as connect is true.       
        while (connected) {
            String line;
            try {
                //Try to read a line from the reader.
                line = in.readLine();
                System.out.println(in.readLine());
                if (in == null) {
                    //No one has sent a message yet.
                    System.out.println("No data recieved");
                }
            
                else {
                    int i = 0;
                    //As long as someone is sending messages.
                    while((line = in.readLine()) != null ){
                         //Make a new Message.
                        Message msg;
                        msg = new Message();
                        //Set the object to the input line.
                        msg.obj = line;
                        //Set an id so it can be identified in the main class and used in a switch.
                        msg.what = i;
                        System.out.println("i is: "+i);
                        //Send the message to the handler.
                        Main.this.h.sendMessage(msg);   
                    }
                }
            }
            catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        
            }           
        }).start(); 
    }

変数 i は、サーバーが送信したものに応じて if ステートメントに含まれていますが、この問題とは関係がないため、それを切り取りました。

問題は、おかしなキャッチです。catch が IOException の場合、アプリはクラッシュします。運が悪かったので、これを Exception に変更し、 e.message を出力してエラーをキャッチし、その原因を確認しました。問題は、この変更で修正されたことです。IOException を単純な Exception に切り替えると、このような問題をどのように修正できますか?

IOException の場合と同様に、プログラムは「エラーをキャッチするつもりはありませんが、エラーはありません」と言いますが、例外を使用すると、「まあ、キャッチできるので続行します」と表示されます。

私のアプリは動作していますが、これを理解できません。なぜ、どのようにこれが起こるのですか?

4

2 に答える 2

2

基本的に、基本Exceptionクラスをキャッチするようにアプリケーションに指示しています。これは、すべての例外クラスがその基本タイプから派生しているため、あらゆるタイプのエラーがキャッチされることを意味します。StringOutOfBoundsException子孫ではないのでIOException、以前はキャッチされておらず、エラーもキャッチされていませんでした。すべての例外をキャッチする代わりに、次のことを試してみてください。

try {
    // Your code here...
} catch (IOException e) {
    Log.e(TAG, "Caught an IOException!", e);
} catch (StringOutOfBoundsException e) {
    Log.e(TAG, "Caught a string out of bounds Exception!", e);
}

StringOutOfBoundsExceptionそもそも何が実際に何を投げているのか判断できません。例から切り取ったのはifステートメントにあるかもしれません。

于 2012-03-09T23:35:27.563 に答える
1
    while (connected) {
        String line;
        try {
            //Try to read a line from the reader.
            line = in.readLine();
            System.out.println(in.readLine());
            if (in == null) {
                //No one has sent a message yet.
                System.out.println("No data recieved");
            }

のテストin == nullは面白い場所にあります。数行前にメソッドを呼び出したという性質上、NullPointerExceptionそのテストが返された場合は、if を受け取るはずです。true明らかに、このコードには少しおかしなところがあります。

in.readLine()2回目に呼び出したときから戻り値を保存できません。有用なものが何も含まれていないことを願っています。(ただし、行を印刷したので、そこに含まれるデータを知りたいのは明らかです。)

line それが何であれ(への最初の呼び出しからin.readLine())、破棄されます。この行で上書きされる前に、それを使用するループには他に何もありません:

                while((line = in.readLine()) != null ){

この時点で、読んだ 2 行は完全に失われます。

これを修正するために何をすべきか完全にはわかりません。私だったら、紙に最初からやり直して、既存のコードを見ずにメソッドが何をすべきかをスケッチし、そのスケッチをコードと比較して、それぞれが見落としているケースを確認したくなるでしょう。 .

于 2012-03-09T23:39:54.857 に答える