Допустим, у меня есть SDK в форме библиотеки Android (aar), который предлагает некоторую базовую обработку мультимедиа (он имеет свой собственный пользовательский интерфейс в виде отдельного действия).В настоящее время любое клиентское Android-приложение при вызове моего SDK отправляет необходимые данные через Bundle.
Теперь по разным причинам может потребоваться дополнительная информация для отправляемых данных после вызова моего SDK, поэтому мне потребуется двадвухсторонняя связь с приложением вызывающего абонента.
Короче говоря, из SDK мне нужно иметь возможность проверить, реализовано ли в клиентском приложении какой-либо интерфейс, чтобы SDK мог использовать его для связи с клиентским приложением (клиент может решить не предоставлять реализацию, и в этом случае SDK откатится к внутреннему, реализация по умолчанию ...).
В любом случае, способ, которым я это сделал изначально, выглядит следующим образом:
В SDK я раскрыл интерфейс поставщика данных:
public interface ISDKDataProvider {
void getMeSomething(Params param, Callback callback);
SomeData getMeSomethingBlocking(Params param);
}
Локальный интерфейс связующего, который должен возвращать экземпляр реализованного интерфейса:
public interface LocalBinder {
ISDKDataProvider getService();
}
Затем на стороне клиентаприложение, использующее SDK, должно предоставлять сервис, который выполняет работу и реализует эти интерфейсы:
public class SDKDataProviderService extends Service implements ISDKDataProvider {
private final IBinder mBinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void getMeSomething(Params param, Callback callback) {
// ... do something on another thread
// once done, invoke callback and return result to the SDK
}
@Override
public SomeData getMeSomethingBlocking(Params param);{
// do something..
// return SomeData
}
public class MyBinder extends Binder implements LocalBinder {
@Override
public ISDKDataProvider getService() {
return ISDKDataProvider.this;
}
}
}
Дополнительно,при вызове SDK приложение Clinet передает ComponentName через параметры пакета:
sdkInvokationOptions.put("DATA_PROVIDER_EXTRAS", new ComponentName(getPackageName(), SDKDataProviderService.class.getName()));
.. из SDK, затем я проверяю, существует ли служба и можем ли мы к ней привязаться:
final ComponentName componentName = // get passed componentname "DATA_PROVIDER_EXTRAS"
if (componentName != null) {
final Intent serviceIntent = new Intent(componentName.getClassName());
serviceIntent.setComponent(componentName);
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
}
где mConnection:
private boolean mBound;
private ISDKDataProvider mService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
final LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};
Кажется, это работает нормально, и выглядит чисто, но мой вопрос, есть ли лучший способ \ практика для достижения такого же типа общения?