2012-03-20 42 views
0

我試圖寫這個程序,更新本身的變量的當前狀態。我打算如何工作是通過定時任務來不斷髮送字符串「更新」到服務器。服務器將識別該字符串,並將在Android設備上發送變量的必要值。但是,我面臨一些問題。字符串「update」發送時沒有錯誤,但是當從服務器返回相應的值時,程序似乎無法讀取答覆。下面是代碼:從插座讀inputstreams導致Android的UI凍結

  //Open socket and initialize data streams 
    try { 
     socket = new Socket(serverIpAddress, applicationport); 
     //in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     //in = new DataInputStream(socket.getInputStream()); 
     out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
       socket.getOutputStream())), true); 
    } catch (UnknownHostException ex) { 
     // TODO Auto-generated catch block 
     ex.printStackTrace(); 
     ShowDialog("Login Error" + ex.getMessage()); 
    } catch (IOException ex) { 
     // TODO Auto-generated catch block 
     ex.printStackTrace(); 
     ShowDialog("Login Error" + ex.getMessage()); 
    } 

    //Create new daemon timer 
    updateData = new Timer(true); 
    updateData.scheduleAtFixedRate(new TimerTask() { 
     @Override 
     public void run() { 
      out.println("update"); 
      UpdateMethod(); 
      }//run 
     }, 1000, 10000);//schedule the delays start/interval here 



}; 

private void UpdateMethod() { 
    //This method is called directly by the timer 
    //and runs in the same thread as the timer. 
    //It calls the method that will work with the UI 
    //through the runOnUiThread method. 
    this.runOnUiThread(Timer_Tick); 
};//timermethod 

private Runnable Timer_Tick = new Runnable() { 
    public void run() { 
     try { 
      //in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      //String getx1 = null; 
      //getx1 = in.readLine(); 
      //if (getx1 != null) { 
       //float updatex1 = Float.parseFloat(getx1); 
       //get_x1 = getx1; 
       //} 
      in = new DataInputStream(socket.getInputStream()); 
      /*try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }*/ 
      x1display = (TextView) findViewById(R.id.x1display); 
      x1display.setText(in.readUTF()); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     finally { 
      if (in != null){ 
       try { 
        in.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
}; 

正如你所看到的,我試圖與這兩個DataInputStream類和BufferedReader嘗試很好,但無濟於事。

編輯:看來,試圖從輸入流中讀取引起我的UI凍結起來。我不知道什麼是錯誤的,因爲我的代碼似乎是沒有錯誤..

任何幫助或建議將不勝感激!

謝謝!

+0

你嘗試使用: InputStream is = socket.getInputStream(); – 2012-03-20 13:41:48

+0

嗨哈克,你能詳細解釋一下我可以如何實現嗎? 謝謝 – Pooty 2012-03-20 14:17:30

+0

我的意思是你換成= new DataInputStream(socket.getInputStream()); InputStream is = socket.getInputStream();因爲我有它使用inputstream – 2012-03-20 14:31:48

回答

0

代碼看起來沒什麼問題。但它不工作,所以看起來你需要把它切碎。

  • 測試套接字的東西是否在沒有定時器的情況下工作。做一個套接字連接並讀取其響應無定時器和UI代碼

  • 如果這樣的作品,介紹了計時器,但不是UI代碼

  • 如果這樣的作品,做整個事情(這是現在不及格)

某處在這個測試過程中,你應該能夠找到罪魁禍首

+0

嗨openmobster,我試圖解決它以這種方式發佈之前stackoverflow。套接字工作正常,計時器工作正常,我的服務器正在定期接收「更新」字符串,但由於某些奇怪的原因,我無法觸摸任何其他按鈕或在Android客戶端上接收服務器輸入。觸摸任何按鈕會導致應用程序崩潰。 – Pooty 2012-03-20 14:16:59

+0

某些東西正在凍結您的UI並導致崩潰,使其看起來像您的按鈕正在崩潰。查看代碼,可能是TimerTick下面的這行代碼可能被凍結等待來自套接字的輸入:x1display.setText(in.readUTF());這在UI線程上執行。也許嘗試讀取計時器任務內的輸入流,並將值提供給UpdateMethod作爲參數 – openmobster 2012-03-20 15:41:54

+0

您好openmobster,看起來您是對的。我已經縮小了導致我的應用程序崩潰的輸入流的罪魁禍首。然而,我不知道如何解決這個問題,因爲我的代碼看起來合乎邏輯和正確。這絕對讓我瘋狂。 :( – Pooty 2012-03-20 20:58:51

0

正如你已經說,讀塊的線程。你不應該在UI線程中讀取一些東西!此外,正如我沒有記錯,關閉輸出前關閉輸出做一些討厭的事情。我建議關閉套接字來代替,而把BufferedReader中回來了,這是應該的樣子:

//Open socket and initialize data streams 
try { 
    socket = new Socket(serverIpAddress, applicationport); 
    in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
      socket.getOutputStream())), true); 
} catch (UnknownHostException ex) { 
    ex.printStackTrace(); 
    ShowDialog("Login Error" + ex.getMessage()); 
} catch (IOException ex) { 
    ex.printStackTrace(); 
    ShowDialog("Login Error" + ex.getMessage()); 
} 

//Create new daemon timer 
updateData = new Timer(true); 
updateData.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
     out.println("update"); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        x1display = (TextView) findViewById(R.id.x1display); 
        x1display.setText(in.readUTF()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      }); 
     try { 
      socket.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }}, 1000, 10000);//schedule the delays start/interval here 

順便說一句,不使用的printStackTrace():Why is exception.printStackTrace() considered bad practice?