2012-07-11 102 views
4

我的Android應用程序使用線程來偵聽來自通過USB連接的PC的套接字連接。在PC打開連接(響應某些用戶驅動事件)之後的某個時刻,我想通過它發送一些數據。如何保持連接線程活着? (我需要使用守護進程嗎?)

public void onCreate(Bundle savedInstanceState) { 

    // SNIP: stuff and nonsense 

    connection = new Thread(new ServerThread()); 
    connection.start(); 
} 

public boolean onTouchEvent(MotionEvent event) { 

    // SNIP: decide what to do; create string 'coordString' 

    Message coordMsg = coordHandler.obtainMessage(); 
    Bundle coordMsgData = new Bundle(); 
    coordMsgData.putString("coords", coordString); 
    coordMsg.setData(coordMsgData); 
    if(coordHandler!=null) 
    { 
     coordHandler.sendMessage(coordMsg); 
    } 

    return false; 
} 

public class ServerThread extends Thread 
{ 
    public void run() { 

     this.setName("serverThread"); 

     Looper.prepare(); 

     coordHandler = new Handler() 
     { 
      @Override 
      public void handleMessage(Message msg) { 
       Log.v(INNER_TAG,"here"); 
      } 
     }; 

     // SNIP: Connection logic here 

     Looper.loop(); 
    } 
}. 

適用年齡,我抓我的頭不知道爲什麼我從來沒有見過的INNER_TAG值出現在我的日誌後,觸摸事件。我可以使用日誌調試追蹤執行到coordHandler!=null區塊,但處理程序似乎從未觸發。

然後它讓我感到震驚:線程可能在完成連接後退出。 呃!不太清楚我以前發生的事情,但我會責怪它,Loop做了一件神奇的事情。

所以我的問題是:我如何讓我的線程運行?官方Android dev reference on threads簡要提及

一個線程也可以做一個守護進程,它使它在後臺運行。

這自然使我的* nix感覺到興奮。 (順便說一句,你有沒有看過新的蜘蛛俠電影呢?這很不錯。)守護神化的答案是什麼?還是我完全失去了情節?

回答

0
  1. 更改connection = new Thread(new ServerThread());到:connection = new ServerThread();

  2. 可能設置/獲取處理程序實例(它是在不同的線程畢竟:))時添加synchronized塊

  3. 循環實際上做的魔術;)

  4. 在onDestroy退出looper serverThread

  5. 最後但並非最不重要(雖然它不涉及處理程序/ Looper主題可能是爲什麼你永遠不會看到在日誌中你期望的):在的boolean onTouchEvent(MotionEvent event)代替使用boolean dispatchTouchEvent(MotionEvent ev)作爲的onTouchEvent由於文檔是Called when a touch screen event was not handled by any of the views under it.所以大概此處理方法不會被調用

編輯: 你確定它執行的sendMessage?順便說一句,你爲什麼使用Log.v?它假定您的日誌記錄級別設置爲詳細,否則日誌將被放棄。我建議使用而不是Log.i

也許試試這個代碼:

ServerThread connection; 
Handler coordHandler; 

public void onCreate(Bundle savedInstanceState) { 
    connection = new ServerThread(); 
    connection.start(); 
} 

@Override 
protected void onDestroy() { 
    synchronized (this) { 
     if(coordHandler != null) { 
      coordHandler.getLooper().quit(); 
     } 
    } 
    super.onDestroy(); 
} 

public boolean dispatchTouchEvent(MotionEvent event) { 

    synchronized (this) { 
     if(coordHandler == null) { 
      Log.i(INNER_TAG, "Handler is null"); 
     } 
     else { 
      Log.i(INNER_TAG, "Handler exists"); 
      coordHandler.sendMessage(
        coordHandler.obtainMessage(
          0, event.toString())); 
     } 
    } 

    return false; 
} 

synchronized void setCoordHandler(Handler handler) { 
    coordHandler = handler; 
} 

public class ServerThread extends Thread { 

    public void run() { 

     this.setName("serverThread"); 

     Looper.prepare(); 

     setCoordHandler(new Handler() { 

      @Override 
      public void handleMessage(Message msg) { 
       Log.i(INNER_TAG, "Inside handler"); 
      } 
     }); 

     Looper.loop(); 
    } 
} 
+0

感謝您的回覆。我會嘗試其他建議,但我可以排除#5。正如我上面所說,我可以確定觸摸事件被調用。 – 2012-07-12 14:15:03