2013-03-12 73 views
1

我有啓動一個IntentService的活性:如何將活動中的消息發送到服務並在服務運行時執行它們?

intent = new Intent(MyApplication.getAppContext(), MyService.class); 
intent.putExtra("EXTRA_DEVICE_ADDRESS", value); 
MyApplication.getAppContext().startService(intent); 

的服務啓動與I發送的MAC地址的藍牙連接。

device = mBluetoothAdapter.getRemoteDevice(macAddress); 

public ConnectThread(BluetoothDevice device) { 
    this.mmDevice = device; 
    BluetoothSocket tmp = null; 
    try { 
     tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID)); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    mmSocket = tmp; 
} 

我聽:

while (true) { 
    try { 
     if (mmInStream.available() != 0) { 
      bytes = mmInStream.read(buffer);  
      String readMessage = new String(buffer, 0, bytes); 
      sendMessageToActivity("incoming", readMessage); 
     } else { 
      SystemClock.sleep(100); 
     } 

和發送接收到的消息回活動:

public void sendMessageToActivity(String type, String message) { 
    intent = new Intent(BROADCAST_ACTION); 
    intent.putExtra(type, message); 
    sendBroadcast(intent); 
} 

我用BroadcastReceiver從服務接收消息:

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     updateUI(intent); 
    } 
}; 

我從活動調用(問題的部分):

private void writeOut(final String message) { 
    msg = message; 
    byte[] send = msg.getBytes(); 
    MyService.write(send); 
} 

這是該服務的靜態write()方法:

public static void write(byte[] out) { 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (obj) { 
     if (mState != STATE_CONNECTED) 
      return; 
     r = mConnectedThread; 
    } 
    // Perform the write unsynchronized 
    r.write(out);` 
} 

我的問題:以上所有作品作爲意圖除了MyService.write(send)。 UI卡住了。我試圖使用AsyncTask,但沒有奏效。我想我需要停止使用該靜態方法並將消息發送到服務並讓他完成這項工作。我相信我需要在活動中初始化一個Handler,並通過startService()將其發送給服務。

我想跟蹤進出服務的消息。它與傳入的消息正常工作。我需要找出一種方法來正確接收來自活動的消息,執行它們,然後將信息發送回活動。

+0

是我的問題複雜嗎? – wervdon 2013-03-12 11:23:04

+0

你需要A /不要因爲你的第一個問題在20小時後沒有回答而提出第二個問題。 B /閱讀關於http://developer.android.com/guide/components/bound-services.html C/define「在AsyncTask的上下文中不起作用」,並詳細說明你如何嘗試。 D /考慮廣播和接收器。 – njzk2 2013-03-13 09:11:16

回答

3

首先,關於IntentService

的所有請求都在一個工作線程處理 - 他們可能只要採取必要的(並不會阻止該應用程序的主循環),但只有一個請求將一次處理。

因此,請考慮將您的代碼移動到Service。我不確定藍牙連接和NetworkOnMainThreadException,但以防萬一:請注意Service在主UI線程上運行,所以爲了避免此類異常,您需要在服務中使用類似Thread的內容。不要使用AsyncTask,因爲AsyncTasks應該理想地用於短操作(最多幾秒鐘)。另外請注意,系統將自動管理服務的生命週期,你不應/無法互動它以任何靜態方法。

現在回到你的問題。您使用廣播接收器的方式(將消息從服​​務發送到活動)是正確的,但請考慮使用ResultReceiver(API 3+中提供)。我想,使用ResultReceiver比發送廣播消息更好。您可以將ResultReceiver放入Intent

而且要將活動的消息發送到服務,我假設您已轉移到Service。您可以將任何東西放入Intent並再次撥打startService()發送。你會得到onStartCommand()的意圖。或者,如果您使用this technique綁定了服務,則可以從該活動內部直接調用服務的方法直接

在SDK中有一些使用服務的示例項目 - 文件夾[Android SDK]/samples/。在模擬器上,您可以在名爲API Demos的應用程序中測試這些項目。

+0

感謝您提供的信息,我們會進行必要的更改並回復。通過startService()傳遞意圖的 – wervdon 2013-03-13 09:39:06

+0

工作。我目前的設置是:帶藍牙連接線程的IntentService。服務到活動:intent +廣播接收器。 Activity-to-Service:intent-startService()。 – wervdon 2013-03-13 12:03:47

+1

@wervdon我認爲你不應該使用IntentService。如文檔所述,每次調用'startService()'都會將服務的新實例推送到隊列中。隊列中的每個項目都會彈出並執行。關於'Service',你可以多次調用'startService()',但是隻有一個在後臺運行的服務實例。我想你可以考慮轉向「服務」? – 2013-03-13 20:07:33

相關問題