2012-03-16 3 views
5

再度LocalServicesに関する質問。 onDestroy()の後、既存のサービスにどのようにバインド(再)しますか?実行中のサービスへのバインド(finish()の後))/コールバックハンドラ

問題: 私はサービスにバインドし、アクティビティからサービスを開始しています。 UI上でコールバック(プログレスバーを更新)のために、実行可能オブジェクトをバインダーにポストしています。このアクティビティを閉じると、OSはライフサイクルを終了し、アクティビティを破棄してonDestroy()を呼び出します。これをシミュレートして、onPause()メソッドでfinish()を呼び出します。したがって、アクティビティを再起動すると、同じサービスに再度バインドする方法は?私はServicesがSingeltonだと思っていましたが、私が再バインドしようとしているときに、別のバインダーのリファレンスがあります。したがって、binder.callbackHandler.post(binder.progressHandler);には、以前のバインダー/コールバック/ progressHandlerへの参照がまだありません。新しいバインダーへの参照はありません。 サービスのコンストラクタさえ、もう一度呼び出されます!

サービスからコールバックオブジェクト(作業中)によって更新されるプログレスバーを持つソリューションはありますか。アクティビティを閉じる/ onDestroy()。戻って、プログレスバーを続けますか?

私のコードは非常に大きいですが、Szenarioを再作成:

public class MyService extends Service { 
     private final LocalBinder binder = new LocalBinder(); 

     public class LocalBinder extends Binder implements TestRunServiceBinder { 
      private Handler callbackHandler; 
      private ServiceStartActivity.RunOnServiceProgress onProgress; 

      @Override 
      public void setActivityCallbackHandler(Handler messageHandler) { 
       callbackHandler = messageHandler; 
      } 

      @Override 
      public void setServiceProgressHandler(RunOnServiceProgress runnable) { 
       onProgress = runnable; 
      } 

       public void doSomething(){ 
        _doSomething(); 

     }; 

     private void _doSomething(){ 
     while(...){ 
      //do this a couple of times (could take up to 10min) 
      binder.callbackHandler.post(binder.progressHandler); 
      wait() 
     } 
     } 

    } 

_

public class ServiceStartActivity{ 
private final Handler messageHandler = new Handler(); 
    private ServiceConnection mTestServiceConnection = new ServiceConnection() { 


     @Override 
     public void onServiceDisconnected(ComponentName name) { 
      testRunBinder = null; 
     } 

     @Override 
     public void onServiceConnected(ComponentName name, IBinder service) { 
      testRunBinder = (TestRunServiceBinder) service; 
      testRunBinder.setActivityCallbackHandler(messageHandler); 
      testRunBinder.setServiceProgressHandler(new RunOnServiceProgress()); 
     } 
     }; 

    @Override 
    protected void onStart() { 
    super.onStart(); 

    // bind to the Service 
    final Intent serviceIntent = new Intent(ServiceStartActivity.this, 
      MyService.class); 
    getApplicationContext().bindService(serviceIntent, 
      mTestServiceConnection, Context.BIND_AUTO_CREATE); 

    } 
    @Override 
    protected void onStop() { 
    super.onStop(); 
    getApplicationContext().unbindService(mTestServiceConnection); 
    } 
     public class RunOnServiceProgress implements Runnable { 
      @Override 
      public void run() { 
       //do something on the UI! 
        } 
     } 
} 

答えて

8

私は今それを得ました。あなたはbindService()でサービスを開始すると、それがバインドされたサービスのみ限り、別のアプリケーションとして

実行次のようになります。あなたはgetApplicationContext().bindService(serviceIntent,mTestServiceConnection, Context.BIND_AUTO_CREATE);

理由を使用してサービスにバインドする前に解決策を明示的に呼び出しstartService(serviceIntent);にありますコンポーネントがバインドされています。

あなたはstartService()でサービスを開始する場合は、例えば持っている場合、それは

だから、無期限にバックグラウンドで

を実行することができますすることができますUIのprogessbarを更新し続けたい場合は、サービスを開始し、onResume()/ onPause()でバインドしてアンバインドする必要があります。しかしcarfullする:あなたが手動でサービスを開始したので、また、手動でそれを停止する必要があります。これを行う最も簡単な方法は、サービスが作業を終えたときにstopSelf()に電話することです。

このソートは、アクティビティからの適切なバインドをカバーします。アクティビティが破壊された後、またはオリエンテーションが変更された後であっても、同じサービスへの進捗バー。

+0

私のために働いた。バインディング時にgetApplicationContext()を使用する場合は、バインドを解除するときに再度使用してください。 – fersarr

関連する問題