Нужно объяснить - PullRequest
       16

Нужно объяснить

0 голосов
/ 10 марта 2012

Так что это самая странная вещь, случившаяся со мной во время программирования.Да, я не профессионал в программировании, но я учусь на ходу.У меня есть приложение, говорящее с сервером, сокет в главном потоке, чтение выполняется в отдельном классе и потоке, а запись в отдельный класс с помощью asynctask.

Проблема в LocationManager.Я мог нормально общаться с сервером и писать / читать команды, я реализовал LocationManager и его слушатель.

Затем я приступил к реализации метода обновления моего текстового представления новыми координатами в locatinChanged.Все идет нормально.Дело в том, что когда я использую элемент управления «Эмулятор» в «Затмении» и отправляю координаты, приложение рухнуло со значением 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 в зависимости от того, что отправил сервер, но я вырезал ее, поскольку она не имеет ничего общего с этой проблемой.

Проблема в том, что это ужасный улов.Когда выгода - IOException, приложение вылетает.Из глупой удачи я изменил это на Exception и напечатал e.message, чтобы поймать ошибку и посмотреть, что ее вызвало.Дело в том, что это изменение исправило это.Как переключение IOException на простое Exception может решить проблему, подобную этой?

Как и в случае с IOException, программа говорит: «Эй, ты не собираешься поймать ошибку, но ошибки нет», а с Exception - «Хорошо, теперьВы могли бы поймать это так плохо, продолжайте ".

Мое приложение работает, но я просто не могу понять это, почему и как это происходит?

Ответы [ 2 ]

2 голосов
/ 10 марта 2012

По сути, вы говорите приложению перехватить базовый класс 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, который вы вырезали из своего примера.

1 голос
/ 10 марта 2012
    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, если бы этот тест когда-либо возвращал true по природе вызова методов для него несколькими строками ранее. Очевидно, что-то немного смешно с этим кодом.

Вы не можете сохранить возвращаемое значение из in.readLine() при втором вызове. Надеюсь, в нем не было ничего полезного. (Хотя, поскольку вы печатаете строку, вы, очевидно, хотели знать, какие данные в ней содержатся.)

Независимо от того, что line было (от первого звонка до in.readLine()), оно выбрасывается; нет ничего другого в цикле, который использует его до того, как он будет перезаписан в этой строке:

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

На этом этапе две строки, которые вы прочитали, исчезли навсегда.

Я не совсем уверен, что нужно сделать, чтобы это исправить; если бы это был я, мне бы очень хотелось начать с листа бумаги и набросать, что должен делать метод, не глядя на существующий код, а затем сравнить эскиз с кодом, чтобы увидеть, какие случаи пропущены в каждом из них. .

...