2012-01-25 53 views
1

我在將服務綁定到Android中的活動時遇到問題。發生在活動的問題:在調用服務之前綁定服務

public class ServiceTestActivity extends Activity { 

private static final String TAG = "ServiceTestAct"; 
boolean isBound = false; 
TestService mService;  

public void onStopButtonClick(View v) { 
    if (isBound) { 
     mService.stopPlaying(); 
    } 
} 
public void onPlayButtonClick(View v) throws IllegalArgumentException, IllegalStateException, IOException, InterruptedException { 
    if (isBound) { 
     Log.d(TAG, "onButtonClick"); 
     mService.playPause(); 
    } else { 
     Log.d(TAG, "unbound else"); 
     Intent intent = new Intent(this, TestService.class); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
    } 
} 


private ServiceConnection mConnection = new ServiceConnection() { 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     isBound = false; 

    } 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     LocalBinder binder = (LocalBinder) service; 
     mService = binder.getService(); 
     isBound = true;   
    } 
    }; 
} 

一個isBound告知用戶,如果服務(稱爲TestService的)已經被綁定到活動中。 mService是對服務的引用。

現在,如果我第一次調用「onPlayButton(..)」,並且服務沒有被綁定,bindService(..)被調用,isBound從false切換到true。然後,如果我再次調用「onPlayButton(..)」,它會在服務對象上調用「playPause()」。到這裏一切工作正常。

但我想「playPause()」被調用的服務已綁定之後,讓我改變了我的代碼如下:

public void onPlayButtonClick(View v) throws IllegalArgumentException, IllegalStateException, IOException, InterruptedException { 
    if (isBound) { 
     Log.d(TAG, "onButtonClick"); 
     mService.playPause(); 
    } else { 
     Log.d(TAG, "unbound else"); 
     Intent intent = new Intent(this, TestService.class); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
     mService.playPause(); 
    } 
} 

從這點上我得到一個NullPointerException,因爲MSERVICE沒有按沒有對綁定服務的引用,它仍然是空的。我通過在代碼中的不同位置記錄mService的值來檢查該值。

關於我在做什麼的任何提示錯誤在這裏?我對android中的編程(特別是綁定)服務很新,但我仍然沒有看到我的版本之間的主要區別在哪裏。

回答

2

一個解決方案是調用onServiceConnected()中的playPause()。另一種解決方案是用一個自定義的意圖調用startService(),它將告訴服務器進行播放。我想你可能想考慮重新設計。我會嘗試設計服務,以便在活動啓動時啓動並綁定到服務,並在活動停止時停止服務。如果您需要一個在活動生命週期內保持活動的服務,請擴展Application類,然後您可以使用onCreate()方法啓動該服務。

3

服務的綁定異步發生,即如果bindService()返回但是onServiceConnected()完成時服務可能不會被綁定。因爲那個mService仍然是空的,並拋出異常。 一個解決方案是默認禁用按鈕(在XML或onCreate())並啓用onServiceConnected()中的按鈕。

+0

似乎是一個很好的觀點。我現在遇到的問題是我想要有相同的按鈕來啓動服務和播放音樂。我看到,我必須等到onServiceConnected完成後,纔可以通過直接等待(while(!isBound){})來做到這一點?我已經嘗試過,並通過日誌記錄,我注意到,只有在onPlayButton完成時,onServiceConnected()的底部纔會到達。 – user1169637

+0

我建議不要這樣做。你爲什麼不直接從onServiceConnected播放音樂(可能在做一些檢查之前,比如檢查音樂沒有播放什麼)。 – Stefan