2012-06-11 61 views
1

我正試圖在我的服務和活動設置之間進行雙向通信。爲了做到這一點,我像平常一樣開始我的服務,發送消息並將replyTo設置爲我的活動中的Messenger,然後將其發送給我的服務。這樣我有一個參考在兩個方向發送消息。這裏是我的Activty一些相關的代碼:)服務未初始化,返回空指針異常

private Messenger mService = null; 
private final Messenger mMessenger = new Messenger(new IncomingHandler()); 

private ServiceConnection mConnection = new ServiceConnection() 
{ 
    public void onServiceConnected(ComponentName className, IBinder service) 
    { 
     mService = new Messenger(service); 
     mBound = true; 
    } 

    public void onServiceDisconnected(ComponentName className) 
    { 
     mService = null; 
     mBound = false; 
    } 
}; 

private void initMessenger() 
{ 
    Message messageHandler = Message.obtain(null, NetworkService.MSG_GET_HANDLER, 0, 0); 
    messageHandler.replyTo = mMessenger; //Set the replyTo to give a reference 
    try 
    { 
     mService.send(messageHandler); 
    } 
    catch(RemoteException e) 
    { 
     e.printStackTrade(); 
    } 
    catch(NullPointerException e) 
    { 
     e.printStackTrace(); //Why!!! 
    } 
} 

public void onCreate() 
{ 
... 
    //Create the intent to start the network service 
    Intent iService = new Intent(this, NetworkService.class); 
    int[] connectionConfig = {CONNECTION_BT}; 
    iService.putExtra(CONNECTION_CONFIG, connectionConfig); 
    bindService(iService, mConnection, Context.BIND_ABOVE_CLIENT); 
    startService(iService); 
    initMessenger(); 
} 

產生NullPointerException當我嘗試打電話mService.send(拋出,很可能是因爲MSERVICE在當時是零。如果我移動Button的OnClickListener中的initMessenger()代碼,它會正常工作,這是混淆的地方。開始服務使用它之後,我應該等待一段時間嗎?

回答

2

mService在這個階段是null表明,這個時候你的服務沒有(還)被稱爲onServiceConnected()

不幸的是,documentation並不表示會有bindService()之間返回,並在ServiceConnection的方法被稱爲一個缺口。

逸岸,bindService()應該返回true當服務已啓動,一旦代碼經過這一階段的服務應該要麼啓動或沒有意思。因此,我會在調用initMessenger()之前檢查bindService()是否返回true,因爲服務可能無法正確啓動。

這也有可能是內onServiceConnected()代碼拋出異常(其中,因爲它是可能的它被稱爲一個工作線程,可能不會引起你的應用程序崩潰),您可能想回來看看你的日誌對檢查是否是這種情況。

此外,startService(iService);是多餘的在此背景下,bindService()開始服務,在服務調用startService只需發送的這一條消息。

1

是的。一旦你知道你必須使用這個服務,你應該只使用這個服務。 由於您試圖在嘗試綁定服務後立即嘗試使用您的服務,因此無法保證您將連接到該服務。有時服務可能會立即綁定,因此您不會崩潰。有時會花費更長的時間,因此您撥打initMessenger()將導致您的NPE,因爲該服務尚未連接。

將您的initMessenger()呼叫移動到您的按鈕點擊可以讓您的服務時間綁定。此外,你應該檢查,以確保您綁定(即使你給它時間),因爲結合可能會失敗

3

爲什麼不叫initMessenger()onServiceConnected()方法是什麼?這樣mService肯定會被分配。