2012-04-19 33 views
0

我想編寫一個連接到遠程服務的模塊。Android:調用遠程Messenger服務的同步方法

該模塊可供開發人員在其應用程序中用於連接特定(藍牙)硬件。然後它應該連接到一個單獨的遠程服務,可以單獨在市場上更新。

由於遠程服務只允許同時使用它的所有應用程序只有一個線程(通過藍牙只有一個連接),所以我選擇了使用AIDL的信使方法。

我的問題是現在我想在我的公共API中提供一個同步方法,但服務返回一個處理程序 - 並且據我所知,處理程序將全部等待當前任務完成...那麼有什麼方法可以在不同的線程中得到答案?

同步方法的代碼,因爲我想它是:預先

responseDataSync = new Sync<ResponseData>(); 

    // Send message 
    Message msg = Message.obtain(null, Constants.DATA, 1, 0); 

    send(msg); 

    try { 
     ResponseData responseData = responseDataSync.get(); 

     // with responseDataSync using a countdown latch to synchronize... 
// but it never fires thanks to the handler. 
//etc... 

感謝。我希望我的問題有點可以理解......;)

/編輯: 我想要一些從服務器返回數據的方法。像

public ResponseData returnResponse(Data dataToSend) 

,但我不能等待該服務的回報,因爲那時我被困在線程塊什麼在處理程序從返回...

+0

通過你的apk,以及一個公共API,必須包含在其他想要使用該服務的應用程序中? – zapl 2012-04-19 23:00:12

+0

你讓我了。 ;)圖書館有附加功能,並應儘可能簡單地訪問服務 - 因此需要一個同步方法 – domenukk 2012-04-20 09:16:45

回答

3

一個Handler與一個消息隊列關聯。如果你從任何一個線程發送一個Message,它將會在那裏排隊。

接收所有消息的線程將從隊列中獲取適當的消息並逐個處理它。

對你有意義,如果你有一個處理程序,並且你通過你的處理程序運行所有的消息,你不需要同步,因爲一切都在一個線程中處理。

編輯:創建一個後臺線程處理消息的處理程序:

HandlerThread ht = new HandlerThread("threadName"); 
ht.start(); 
Looper looper = ht.getLooper(); 
Handler.Callback callback = new Handler.Callback() { 

    @Override 
    public boolean handleMessage(Message msg) { 
     // handled messages are handled in background thread 
     return true; 
    } 
}; 
Handler handler = new Handler(looper, callback); 

handler.sendEmptyMessage(1337); 

EDIT2:等待消息可能像這樣工作

// available for all threads somehow 
final Object waitOnMe = new Object(); 

HandlerThread ht = new HandlerThread("threadName"); 
ht.start(); 
Looper looper = ht.getLooper(); 
Handler.Callback callback = new Handler.Callback() { 

    @Override 
    public boolean handleMessage(Message msg) { 
     // handled messages are handled in background thread 
     // then notify about finished message. 
     synchronized (waitOnMe) { 
      waitOnMe.notifyAll(); 
     } 
     return true; 
    } 
}; 
Handler handler = new Handler(looper, callback); 

// in a different Thread: 
synchronized (waitOnMe) { 
    handler.sendEmptyMessage(1337); 
    try { 
     waitOnMe.wait(); 
    } catch (InterruptedException e) { 
     // we should have gotten our answer now. 
    } 
} 
您有分發(遠程)服務
+0

謝謝,我明白這一點。但是,這是我的問題。我想有一個同步方法,例如 public SomeValue returnSomeValue(SomeParameter someParameter) 但我不能等待服務的結果,因爲只要我卡住執行方法,我的處理程序就不會返回任何東西... – domenukk 2012-04-20 09:58:13

+0

好吧,我明白了。這稍微複雜一些:基本上你需要設置一個機制,首先發送一個消息到你的服務,然後等待你從'returnSomeValue()'中的服務接收到的消息。另一種可能性是帶有AIDL接口的常規服務,它可以在內部處理此問題。您可以在這樣的服務中調用真正的方法,但如果您不希望用戶這樣做,您仍然必須在'returnSomeValue()'中管理服務連接。 – zapl 2012-04-20 10:12:12

+0

我需要第一種方法。 AIDL的問題在於,我將不得不基本改寫所有內容,並且必須自己實現使用Messengers自然發生的同步。 你有什麼想法如何等待處理程序?由於處理程序是同步的,我似乎無法找到任何函數如何等待它的方法。 (雖然該函數正在等待處理程序不返回。)我可以將處理程序以某種方式放入不同的線程?我遇到了HandlerThread,但無法弄清楚它是否可以幫助我...... – domenukk 2012-04-20 11:26:29