2011-09-09 90 views
0

我計劃通過TCP套接字與PC程序進行通信的Android應用程序。該應用程序將有幾個活動(佈局),每個活動(佈局)代表連接到PC的不同物理設備。我希望有一個TCP套接字連接到PC服務器,當應用程序第一次打開,然後在後臺運行。當用戶具有Device-A的活動時,打開TCP套接字應持續向主機發送Device-A狀態請求,然後使用最新數據更新UI。Android應用程序TCP工作人員

我一直在尋找不同的可能性來運行後臺任務,我不確定在這種情況下哪個選項是最好的。我的TCP操作系統應該連續運行在一個線程上嗎?我知道一個服務只能用於非阻塞操作,並且我不能保證網絡交易將是即時的(特別是當連接到網絡丟失時)。

如果我要在線程中運行通信,提醒UI新數據已到達的最佳方式是什麼?另外,當用戶切換到不同的活動時,提醒線程開始請求關於不同設備的信息的最佳方式是什麼?

回答

1

我們正在構建一個Android應用程序,該應用程序通過TCP套接字與硬件進行通信,該套接字監聽來自設備的各種事件並通過用戶操作與其通信。與您即將要做的事情類似,我們的應用也有幾項活動,它們根據活動的上下文獲取不同的數據。對於應用程序,我們做了以下方法:

  • 創建一個響應和請求處理程序負責打開套接字輸出和輸入流。
  • 我們在自己的Thread上運行這兩個。請求處理程序正在從包含請求的阻塞隊列中獲取請求
  • 每個請求都使用其類型,請求標識,時間戳和處理程序進行標識。
    • 類型識別請求的(中,設備類型中的情況下)
    • 甲處理程序是使用Android Handler,負責處理與特定ID和類型的請求的上下文。在你的情況下,你將有DeviceAHandler,DeviceBHandler等,你將與特定的id和類型相關聯。通過這種方法,您的處理器可以處理特定設備
  • 特定的UI更新響應處理程序,我們有一個阻塞的InputStream是等待響應,一旦收到響應,我們相匹配的響應ID爲請求標識並獲取與標識關聯的處理程序
  • 將上下文更改爲特定活動後,我們將發送具有不同請求類型的請求。就你而言,無論何時更改活動,都可以使用onStart向服務器發送請求類型切換。由於您註冊的以前的處理程序處理特定的上下文(通過請求類型),因此如果它們與新的請求類型不匹配,它們將忽略該響應。

請求和響應處理程序被實現爲的AsyncTask,下面是對ResponseHandler所存根,讓你可以更好地理解了我寫的:


public class ResponseHandler extends AsyncTask { 
    boolean isConnectionClosed = false; 

    @Override 
    protected Integer doInBackground(Void... params) { 
     int errorCode = 0; 

     try { 
      // while not connection is not close 
      while(!isConnectionClosed){ 
       // blocking call from the device/server 
       String responseData = getResponse(); 

       // once you get the data, you publish the progress 
       // this would be executed in the UI Thread 
       publishProgress(responseData); 
      } 
     } catch(Exception e) { 
      // error handling code that assigns appropriate error code 
     } 

     return errorCode; 

    } 

    @Override 
    protected void onPostExecute(Integer errorCode) { 
     // handle error on UI Thread 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     String responseData = values[0]; 

     // the response contains the requestId that we need to extract 
     int requestId = extractId(responseData); 

     // next use the requestId to get the appropriate handler 
     Handler uiHandler = getUIHandler(requestId); 

     // send the message with data, note that this is just the illustration 
     // your data not necessary be jut String 
     Message message = uiHandler.obtainMessage(); 
     message.obj = responseData; 
     uiHandler.sendMessage(message); 
    } 

    /*** 
    * Stub code for illustration only 
    * Get the handler from the Map of requestId map to a Handler that you register from the UI 
    * @param requestId Request id that is mapped to a particular handler 
    * @return 
    */ 
    private Handler getUIHandler(int requestId) { 
     return null; 
    } 

    /*** 
    * Stub code for illustration only, parse the response and get the request Id 
    * @param responseId 
    * @return 
    */ 
    private int extractId(String responseId) { 
     return 0; 
    } 

    /*** 
    * Stub code for illustration only 
    * Call the server to get the TCP data. This is a blocking socket call that wait 
    * for the server response 
    * @return 
    */ 
    private String getResponse() { 
     return null; 
    } 
} 
+0

感謝您的例子。這真的很有幫助。問題,你在哪裏創建TCP套接字,以便它存在供所有活動訪問?上面的類應該被編碼爲單例嗎? – PICyourBrain

+0

我有一個包裝請求和響應處理程序的類,並且該類是可以從其他活動 – momo

+0

ah ok訪問的單例。這是我失蹤的一塊。這非常有幫助。我在C#中編程了很多,但這是我的第一個java/android工作! – PICyourBrain

相關問題