Как клиентский процесс (в Android IPC с aidl) знать о классе удаленного сервера? - PullRequest
0 голосов
/ 15 апреля 2019

В официальном документе Android Aidl пример клиента IPC явно объявляет намерение с целевым объектом «RemoteService.class».Однако, когда сервер и клиент не находятся в одном и том же пакете, клиент не должен знать, что такое «RemoteService», если не установлена ​​зависимость.Как работает пример?

ref: https://developer.android.com/guide/components/aidl.html

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

В документах Android,

Intent intent = new Intent(Binding.this, RemoteService.class);
intent.setAction(IRemoteService.class.getName());
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

В настоящее время я ожидаю, что это должно быть изменено на:

Intent intent = new Intent("<remote-service-intent-filter-in-androidmanifest>");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

1 Ответ

1 голос
/ 16 апреля 2019

Вы находитесь на правильном пути, но если вы добавите действие намерения в манифест, то вам также следует указать имя пакета при привязке службы.

intent.setPackage("<remote service package name>");

Внимание: для обеспечениячто ваше приложение защищено, всегда используйте явное намерение при запуске Сервиса и не объявляйте фильтры намерений для ваших сервисов.Использование неявного намерения для запуска службы представляет собой угрозу безопасности, поскольку вы не можете быть уверены в том, что служба отвечает на это намерение, и пользователь не может видеть, какая служба запускается.Начиная с Android 5.0 (уровень API 21), система выдает исключение, если вы вызываете bindService () с неявным намерением.https://developer.android.com/guide/components/services

Фрагмент. Вот как я подключаюсь к удаленной службе в другом приложении с помощью API setClassName.

Примечание : этот подход ненеобходимо действие намерения в файле манифеста.

при активности клиента.

/**
 * Init Service
 */
private void initService() {
    if (mSampleService == null) {
        Intent i = new Intent();

        // set intent action
        i.setAction("com.hardian.sample.aidl.ISampleService");
        // mention package name with service's canaonical name
        i.setClassName("com.hardian.sample", "com.hardian.sample.aidl.SampleAidlService");

        // binding to a remote service
        bindService(i, mSampleServiceConnection, Service.BIND_AUTO_CREATE);
    } 
}

при обслуживании

 /**
 * {@inheritDoc}
 */
@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG, "onBind called");
    if (ISampleService.class.getName().equals(intent.getAction())) {
        return mSampleServiceBinder;
    }
    return null;
}
...