Нужно ли иметь одно ServiceConnection для каждой привязки сервиса?

У меня несколько андроид Serviceс которым я хочу связать в моем Activity, поэтому я могу контролировать несколько действий от пользователя.

Чтобы иметь возможность связывать каждый Сервис, а у меня их будет несколько, нужно ли мне несколько частных 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;
    }
};

Или мне нужен класс менеджера между моей Активностью и Сервисами, который обеспечивает лучшее использование и понимание ограниченных Сервисов?

2 ответа

Решение

Нужно ли иметь один serviceConnection для каждого сервиса Android?

Я полагаю, вы спрашиваете, можете ли вы использовать то же самое serviceConnection для нескольких услуг. Там нет необходимости иметь один для каждого подключения службы, но это, вероятно, лучший подход. Я вижу в вашем коде это

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

Это очень сбивает с толку... похоже, что сервис можно разделить на два разных сервиса!!

Вы поймете, что onServiceConnected Обратный вызов - это то, где происходит большая часть магии, когда вы (Activity) наконец можете получить указатель на ваш Сервис и начать вызывать методы и взаимодействовать с вашим сервисом. Если вы хотите использовать то же самое serviceConnection для различных сервисов вам необходимо выяснить, какому пользовательскому подклассу принадлежит объект IBinder, а затем привести их соответствующим образом. Уффф, слишком много проблем. Я бы порекомендовал иметь один serviceConnection за услугу.

Или мне нужен класс менеджера между моей деятельностью и службами, который обеспечивает лучшее использование и понимание ограниченных служб?

И для этого, и для вашего первого вопроса вы можете делать все, что захотите. Там нет подход лучше, чем другой (ИМХО), и лучший из них тот, который вы понимаете лучше и заставляет вас чувствовать себя более комфортно.

Один ServiceConnection Экземпляр можно использовать для привязки к нескольким Сервисам.

В ServiceConnection.onServiceConnected(), вам нужно проверить, какой сервис был связан (используя className.getClassName() или же className.getPackageName()) и поместите его в соответствующее поле / переменную и т. д.

Я использовал эту тему в качестве ссылки, хотя я изменил ее в соответствии со своими потребностями.

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;
        }
    }
}
Другие вопросы по тегам