2012-01-25 8 views
1

サービスをAndroidのアクティビティにバインドする際に問題があります。問題は、アクティビティで発生します(TestServiceと呼ばれる)サービスがすでに活動にバインドされている場合サービスをバインドしてからメソッドを呼び出す

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を伝えます。 mServiceはサービスへの参照です。

私が "onPlayButton(..)"を初めて呼び出すと、バインドされていないサービスでbindService(..)が呼び出され、isBoundがfalseからtrueに切り替わります。次に、 "onPlayButton(..)"をもう一度呼び出すと、サービスオブジェクトの "playPause()"が呼び出されます。ここまではうまくいく。

しかし、私は「playPause()は、」サービスがバインドされた直後に呼び出されるので、私はこれに私のコードを変更したい:私はNullPointerExceptionが取得にmServiceはdoesnのため、この時点から

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(); 
    } 
} 

バインドされたサービスへの参照がありますが、それはまだnullです。 mServiceの値をコード内の別の位置に記録することでチェックしました。

私がここで間違っていることに関するヒントを教えてください。私はアンドロイドでプログラミング(特にバインディング)サービスを始めたばかりですが、私のバージョンとの大きな違いはまだありません。

答えて

2

解決策の1つは、onServiceConnected()でplayPause()を呼び出すことです。別の解決策は、サービスを再生するように指示するカスタムインテントでstartService()を呼び出すことです。私はあなたが再設計について考えることを望むかもしれないと思います。サービスを設計して、アクティビティの開始時にサービスを開始およびバインドし、アクティビティが停止したときにサービスを停止できるようにします。アクティビティのライフタイムを過ぎてもアクティブになるサービスが必要な場合は、Applicationクラスを拡張し、onCreate()メソッドでサービスを開始できます。

3

サービスのバインディングは非同期的に発生します。つまり、bindService()が返ってもonServiceConnected()が完了していれば、サービスはバインドされていない可能性があります。そのため、mServiceはまだnullであり、例外がスローされます。 1つの解決策は、(XMLまたはonCreate()の)デフォルトでボタンを無効にし、onServiceConnected()のボタンを有効にすることです。

+0

良い点のようです。私が今行っている問題は、サービスと再生音楽を開始するために同じボタンを使いたいということです。私はonServiceConnectedが完了するまで待たなければならないことを知っています。文字通りちょうど待っている間に(while(!isBound){})それを行うことができますか?私はすでにそれを試みて、私が気づいたログによって、onPlayButtonが終了したときにonServiceConnected()の底面に到達するだけです。 – user1169637

+0

私はそうしないことをお勧めします。 onServiceConnectedから音楽を再生し始めるのはなぜですか(音楽が再生されていないかどうかを確認するなどの前に、いくつかのチェックをしている可能性があります)。 – Stefan

関連する問題