3

여러 개의 Android Service이 내 Activity에 바인딩되기 때문에 사용자의 여러 작업을 모니터링 할 수 있습니다.각 서비스 바인드 당 하나의 ServiceConnection을 가질 필요가 있습니까?

모든 서비스를 묶을 수 있으려면 몇 가지가 필요합니다. 내 활동에 다음과 같은 몇 가지 개인용 ServiceConnection이 필요합니까?

/** Defines callbacks for service binding, passed to bindService() */ 
private ServiceConnection mConnection = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName className, 
      IBinder service) { 
     // We've bound to LocalService, cast the IBinder and get LocalService instance 
     GPSLocalBinder gpsBinder = (GPSLocalBinder) service; 
     PhotoLocalBinder photoBinder = (PhotoLocalBinder) service; 
     gpsService = gpsBinder.getService(); 
     photoService = photoBinder.getService(); 
     mGpsBound = true; 
     mPhotoBound = true; 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName arg0) { 
     mGpsBound = false; 
     mPhotoBound = false; 
    } 
}; 

제한된 서비스에 대한 사용과 이해를 향상시키는 내 활동과 서비스간에 관리자 클래스가 필요합니까?

답변

1

서비스마다 하나의 serviceConnection이 있어야합니까?

여러 서비스에 대해 동일한 serviceConnection을 다시 사용할 수 있는지 묻는 것으로 가정합니다. 각 서비스 연결마다 하나씩 가질 필요는 없지만 이것이 아마도 가장 좋은 방법입니다. 나는 당신의 코드에서 이것을 보았다

 GPSLocalBinder gpsBinder = (GPSLocalBinder) service; 
     PhotoLocalBinder photoBinder = (PhotoLocalBinder) service; 
     gpsService = gpsBinder.getService(); 
     photoService = photoBinder.getService(); 

이것은 매우 혼란 스럽다. 이것은 서비스가 두 가지 다른 서비스로 던져 질 수있는 것처럼 보인다 !!

onServiceConnected 콜백은 대부분 마술이 일어나는 곳이며, 귀하 (활동)가 마침내 귀하의 서비스에 대한 포인터를 얻고 메소드를 호출하고 서비스와 상호 작용할 수 있음을 알게 될 것입니다. 서로 다른 서비스에 대해 동일한 serviceConnection을 다시 사용하려면 IBinder 객체가 속한 사용자 정의 하위 클래스를 찾아 적절하게 캐스팅해야합니다. Ufff, 너무 많은 문제. 서비스 당 하나의 serviceConnection을 사용하는 것이 좋습니다.

또는 은 제한된 서비스에 대한 더 나은 사용법과 이해를 제공하는 내 활동과 서비스간에 관리자 클래스가 필요합니까?

이 질문과 첫 질문 모두 원하는대로 할 수 있습니다. 다른 것 (IMHO)보다 더 좋은 접근 방법이 없으며 가장 좋은 방법은 당신이 더 잘 이해하고 편안함을 느끼게하는 것입니다.

+0

이 주제에 대한 당신의 enlightment에 대한 Thx. – JoaoFilipeClementeMartins

0

하나의 ServiceConnection 인스턴스를 여러 서비스에 바인딩하는 데 사용할 수 있습니다. ServiceConnection.onServiceConnected()에서

, 당신은 등 (className.getClassName() 또는 className.getPackageName() 사용) 결합 된 서비스를 확인하고 해당 필드/변수에 넣어야 할 것

나는 그것을 수정하지만 내가 참고로 this thread을 사용 내 필요에 맞게

private static final int SERVICE_1_INDEX = 0; 
private static final int SERVICE_2_INDEX = 1; 

/** Array of the subclasses of {@link BaseService}s which have been bound */ 
private BaseService[] mServices; 
/** ServiceConnection which handles the binding/unbinding of the services */ 
private MyServiceConnection mServiceConnection; 

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    mServiceConnection = new MyServiceConnection(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    bindServices(); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    unbindServices(); 
} 

private void bindServices() { 
    Intent service1Intent = new Intent(getActivity().getApplicationContext(), MyService1.class); 
    Intent service2Intent = new Intent(getActivity().getApplicationContext(), MyService2.class); 

    getContext().bindService(service1Intent, mServiceConnection, Context.BIND_AUTO_CREATE); 
    getContext().bindService(service2Intent, mServiceConnection, Context.BIND_AUTO_CREATE); 
} 

private void unbindServices() { 
    if (mServiceConnection != null) { 
     getContext().unbindService(mServiceConnection); 
    } 
} 

private class MyServiceConnection implements ServiceConnection { 
    public void onServiceConnected(ComponentName className, IBinder boundService) { 
     Log.d("className(bound)", className.getClassName()); 
     Log.d("className(Service1)", MyService1.class.getName()); 
     Log.d("className(Service2)", MyService2.class.getName()); 
     BaseService.LocalBinder binder = (BaseService.LocalBinder) boundService; 
     if (className.getClassName().equals(MyService1.class.getName())) { 
      mServices[SERVICE_1_INDEX] = binder.getService(); 
      // call method on your service like: 
      // binder.getService().someMethod(); 
      // (you may need to cast to your actual Service) 
     } 
     else { 
      mBaseServices[SERVICE_2_INDEX] = binder.getService(); 
      // call method on the service like in if-block 
     } 
    } 

    public void onServiceDisconnected(ComponentName className) { 
     if (className.getClassName().equals(MyService1.class.getName())) { 
      mBaseServices[SERVICE_1_INDEX] = null; 
     } 
     else { 
      mBaseServices[SERVICE_2_INDEX] = null; 
     } 
    } 
}