2012-03-09 3 views
0

프로그래밍 할 때 가장 이상한 일입니다. 예, 나는 프로에서 프로그래밍을 배우지 만, 나는가는 것처럼 배우지 않습니다. 필자는 응용 프로그램을 서버, 메인 쓰레드의 소켓, 읽기는 별도의 클래스와 쓰레드로 처리하고 asynctask를 사용하여 별도의 클래스로 작성한다.설명이 필요합니다

문제는 LocationManager입니다. 나는 서버와 통신하고 명령을 잘 읽고 쓰고, LocationManager와 리스너를 구현했다.

그런 다음 locatinChanged의 새 좌표로 내 textview를 업데이트하는 방법을 구현했습니다. 여태까지는 그런대로 잘됐다. 내가 일식에서 에뮬레이터 컨트롤을 사용하여 좌표를 보낼 때 응용 프로그램이 stringOutOfBoundsException으로 추락했습니다 (3 년 동안 프로그래밍 된 IVE가 지금까지 본 적이 없습니다). 나는 그걸 밟은 코드를 보았다. stacktrace, logcat, 콘솔을 읽고 내가 생각할 수있는 모든 곳을 찾았지만 어디에도 없습니다. 내가 마지막으로 readerthread 느릅 나무에 갔다 때까지 다음과 같습니다

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(); 
    } 

문은 서버가 보낸 내용에 따라하지만이 문제와 아무 상관이있다 나는 그 잘라 경우 내가있는 변수입니다.

문제는 괴물입니다. catch가 IOException이면 응용 프로그램이 충돌합니다. 멍청한 행운을 빌어 예외를 Exception으로 변경하고 e.message를 출력하여 오류를 찾아서 원인을 확인합니다. 문제는이 변화가 그것을 고쳤다는 것입니다. 어떻게 IOException을 그냥 평범한 예외로 바꿀 수 있습니까?

IOException의 경우와 마찬가지로 프로그램에서 "오류가 발생하지만 오류가 발생하지 않습니다."라는 예외가 있지만 예외가 있으면 "이제는 잘못 처리 할 수 ​​있습니다."라고 나와 있습니다.

내 앱이 작동하지만이 문제를 파악할 수없는 이유는 무엇이며 어떻게 발생합니까?

+0

코드가 작동한다고 계속해서 말하지만, 이는 틀림없이 거짓이거나, 여기에 있지 않을 것입니다. @twaddington은 문제가 무엇인지 말해주었습니다. IOException 만 잡으면 다른 예외가 발생하면 앱이 중단됩니다. 대신 Exception 잡기는 가능한 모든 예외를 잡아낼 것입니다. 그래서 이상한 일이 있기 때문에가 아니라 모든 가능한 런타임 오류를 무시하고 있기 때문에 앱이 더 이상 충돌하지 않으므로 조용히 계속되지만 불확정 상태가됩니다. – RivieraKid

+0

질문에 대한 오해가있는 것 같습니다. 코드가 작동하기 때문에 나는 여기에 있지만 should shouldnt. 나는 원하는 기능을 가지고있다. 모든 것은해야하는 일을하고 있으며, 이것을 반복해서 시험해보고 있습니다. 서버의 기능에 대한 텍스트 파일을 가진 다른 컴퓨터에서 내 클라이언트와 서버가 나란히 있기 때문에 서버가 응답해야하는 내용을 알고 있습니다. 명령을 보내면 정확한 응답을 얻습니다. 나는 좌표를 설정하고, 나는 응답하는 부분에 if와 intercept를하는 정확한 응답음을 얻는다. 그러나 논리적으로 (나를 위해) 그것은 작동해서는 안됩니다. – Gvs

+0

글쎄, 이건 어때? 모든 예외를 포착하면 스레드를 시작할 수 있지만 예외를 던져 버리는 오류 상태를 올바르게 처리하지 못하고있다. 실제로 예외를 무시하고있다. 스레드가 시작될 수 있으므로 모든 예외를 잡는 것만으로도 사실 무시한 버그를 해결할 수 있다는 인상을줍니다. 원래 코멘트에서 말했듯이, 문제를 무시하고 고치지 않고 있습니다. – RivieraKid

답변

2

기본적으로 응용 프로그램에 Exception 클래스를 잡으라고 말하고 있습니다. 즉, 모든 예외 클래스가 해당 기본 유형에서 비롯되기 때문에 모든 유형의 오류가 발견됩니다. StringOutOfBoundsExceptionIOException에서 내려 오지 않았기 때문에 이전에 잡히지 않았으며 오류가 발견되지 않았습니다. 대신 모든 예외를 잡는, 다음을 시도 할 수 있습니다 : 실제로 시작하는 StringOutOfBoundsException를 던지고 결정 드릴 수 없습니다

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); 
} 

. if 문에서 예제를 생략 할 수 있습니다.

+0

예, 알고 있습니다. 문제는 IOException을 Exception NoTHING으로 변경 한 것뿐입니다. 그렇다면 오류가 발생한 이유는 무엇입니까? catch를 변경하면 오류를 수정해야합니까? 그냥 존재했던 오류 잡기? 무엇이 오류를 일으키는 locationListener 내 좌표를 서버에 보낸 구현 그래서 에뮬레이터 컨트롤을 사용하여 응답을 읽는 동안 충돌했을 좌표를 설정합니다. – Gvs

+0

추가 : 아니오 경우에만 들어오는 메시지를 잡았고 무엇에 따라 설정합니다. 메시지는, 만약 내가 그것을 잡기를 원했던 어떤 것이 아니라면, 단지 system.out.println으로 인쇄되었다. 그렇다면 오류가 수정 된 후에 추가 된 경우 if와 아무 관계가 없습니다. – Gvs

+0

다시 읽고 예 IOException은 문자열에서 outofbound를 catch하지 않지만 catch를 변경하면 분명히 존재하지 않는 문제가 "수정"됩니다. 캐치와 캐치 만 변경하면 응용 프로그램이 제대로 작동하므로 오류가 발생하지 않습니다. 그것은 일식과 같은 느낌이 나는 그 오류를 잡을 수 없다는 귀하의 응용 프로그램을 충돌 메신저를 수정하고 계속할 수 있도록 아프다. – Gvs

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에 대한 테스트는 재미있는 위치에 있습니다. 해당 테스트가 몇 줄 더 일찍 호출 방법의 본질에 의해 true을 반환 할 경우 NullPointerException을 받아야합니다. 분명히이 코드는 다소 재미 있습니다.

두 번째로 호출 할 때 in.readLine()의 반환 값을 저장하지 못했습니다. 나는 그것이 유용한 것을 아무것도 포함하지 않기를 바란다. (당신이 라인을 인쇄하기 때문에 비록, 당신은 분명이 포함 된 어떤 데이터를 알고 싶어.)

무엇이든 line이 (in.readLine()에 대한 첫 번째 호출에서), 그것은 멀리 던져 도착하였습니다; 그것은이 라인에 겹쳐 쓰기 전에 그것을 사용하는 루프에서 아무 것도 없다 :

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

이 시점에서, 당신이 읽은 두 줄은 영원히 사라졌다.

이 문제를 해결하기 위해 무엇을해야하는지 잘 모르겠습니다. 그것이 나라면, 나는 종이로 시작하여 기존 코드를 보지 않고 그 방법이 무엇을해야 하는지를 스케치하고, 스케치와 코드를 비교하여 각각의 경우를 간과 한 사례를 보게된다. .

+0

네,이 코드는 제가 아는 총 스파게티 엉망입니다. 나는 함께 일하면서 쓰레기를 버려야합니다. 아무 것도 고쳐질 필요가 없으며,이 코드가 작동합니다. 문제는 IOException에서 일반 Exception으로 캐치를 변경하는 것입니다. 왜? – Gvs

+0

나는 내 전체 클래스와 하위 클래스를 게시 할 수 있지만 솔직히 말해서 코드는 쓰레기처럼 보일 수 있지만 작동하며 im은 안드로이드와 잘 맞지 않으므로 C# 및 IVE에서 사용 된 "최적이 아닌"옵션을 사용하여 문제를 해결했습니다. 읽기 스레드와 내 코드를 게시하는 것은 나를 괴롭힌다 : p. – Gvs

+0

나는'read' 블록에서'in.readLine()'_twice_를 호출하고 있다는 것을 다시 읽은 것으로 나타났습니다; 첫 번째로 결코 사용하지 않는 변수에 저장하고 두 번째로 값을 인쇄하지만 버리십시오. 두 가지를하고 싶다는 것이 확실합니까? – sarnold