Моя компания выпускает SDK, поставляемый в виде файла aar библиотеки Android. В рамках этого SDK мы определяем сервис:
<service
android:name=".session.internal.ChatSession"
android:description="@string/description"
android:enabled="true"
android:exported="false"
android:label="Network communication service"
/>
Затем эта служба запускается и связывается с дополнительным кодом в SDK:
public boolean bindService(final Runnable whenBound) {
if (connection == null) {
// Make sure the service is running
boolean success = startService();
if(BuildConfig.DEBUG && !success) {
throw new AssertionError("startService failed");
}
connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
chatSession = (IChatSession) service;
if(whenBound != null) {
whenBound.run();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
chatSession = null;
connection = null;
}
};
success = context.bindService(new Intent(context, ChatSession.class), connection, Context.BIND_IMPORTANT);
if(BuildConfig.DEBUG && !success) {
throw new AssertionError("bindService failed");
}
return success;
}
if(whenBound != null) {
whenBound.run();
}
return true;
}
boolean startService() {
boolean success = true;
if(!isServiceRunning()) {
success = context.startService(new Intent(context, ChatSession.class)) != null;
}
return success;
}
Все это прекрасно работает, пока на мобильном устройстве установлено только одно приложение, использующее SDK.
Поскольку служба явно не экспортируется (android:exported="false"
) и неявно не экспортируется (не определено <intent-filter>
), мы ожидали, что это будет нормально работать с несколькими установленными приложениями, причем каждое приложение получит свой собственный частный экземпляр службы, когда bindService
называется.
Что на самом деле происходит, так это то, что ни одно приложение больше не работает, поскольку ни ServiceConnection.onServiceConnected
, ни ServiceConnected.onServiceDisconnected
никогда не вызываются, хотя вызовы context.startService
и context.bindService
возвращают успех.
После установки обоих приложений единственный способ заставить любое из них работать — удалить оба, а затем переустановить только одно. Недостаточно удалить либо независимо.