2012-03-16 2 views
5

다시 LocalServices에 대한 질문입니다. onDestroy() 이후에 기존 서비스에 어떻게 바인딩합니까?실행중인 서비스에 바인딩 (finish() 후)/콜백 핸들러

문제점 : 활동에 서비스를 바인딩하고 서비스를 시작합니다. UI에서 콜백 (진행 막대 업데이트)을 위해 실행 가능한 개체를 바인더에 게시하고 있습니다. 이 액티비티를 닫으면 운영체제가 라이프 사이클을 끝내고 액티비티를 파괴하고 onDestroy()를 호출 할 수 있습니까? 필자는 onPause() 메서드에서 finish()를 호출하여이를 시뮬레이션합니다. 그래서 일단 Activity를 다시 시작하면 같은 서비스에 다시 바인딩하는 방법은 무엇입니까? 나는 서비스가 Singelton이라고 생각했지만 재 바인딩하려고 할 때 다른 바인더 참조를 얻습니다. 따라서 binder.callbackHandler.post(binder.progressHandler);은 이전 바인더/콜백/progressHandler에 대한 참조를 여전히 가지고 있으며 새로운 것이 아닙니다. 서비스의 생성자도 다시 호출됩니다!

서비스에서 콜백 개체 (작업 중)에 의해 업데이트되는 진행률 표시 줄이있는 솔루션이 있습니까? Activity를 닫거나 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

지금 그것을 얻었다. 당신이 사용하는 서비스에 결합하기 전에이 솔루션은 명시 적으로 호출 startService(serviceIntent);이다 getApplicationContext().bindService(serviceIntent,mTestServiceConnection, Context.BIND_AUTO_CREATE);

이유 : 당신이 bindService()과 함께 서비스를 시작하면, 그것은 바운드 서비스가되는

다른 응용 프로그램으로

실행 동안 만 구성 요소가 바인딩됩니다. 당신이 startService()과 함께 서비스를 시작하는 경우, 예를 들어이있는 경우

그래서, 무기한 배경에

를 실행할 수 있습니다 UI에 프로젠 바를 추가하고 계속 업데이트하려면 서비스를 시작하고 onResume()/onPause()에서 바인딩하고 언 바인드해야합니다. 하지만 carfull 수 : 서비스를 수동으로 시작한 이후 또한 수동으로 중지해야. 가장 간단한 방법은 서비스가 작동하면 stopSelf()으로 전화하는 것입니다.

이 소울 톤은 예를 들어 Activity와의 적절한 바인딩을 포함합니다. 활동이 파기되거나 오리엔테이션이 변경된 후에도 동일한 서비스에 대한 진행 표시 줄.

+0

나를 위해 일했습니다. 바인딩 할 때 getApplicationContext()를 사용하면 바인딩을 해제 할 때 다시 사용하십시오. – fersarr

관련 문제