Андромеда обеспечивает коммуникацию между модулями как для локальных, так и для удаленных сервисов.
Примечание: причина, которая отличает локальные сервисы от удаленных, заключается в том, что типы параметров в удаленных сервисах могут быть только примитивными типами или пользовательскими типами, реализующими Parcelable, в то время как типы параметров в локальных сервисах могут быть любыми типами, такими как View и Context.
Документация, или всё же лучше на китайском
Aidl интерфейс и его реализация — это единственные вещи, которые разработчики должны делать. bindService() и определение Service не требуются.
Удаленные сервисы могут быть получены синхронно, а не асинхронно.
Управление задачами с приоритетом процесса осуществляется вместе с жизненным циклом Fragment/Activity.
Поддержка обратного вызова IPC.
Поддержка шины событий для всех процессов.
Примечание: здесь сервис означает интерфейс и его реализацию, а не компонент Service.
Сравнение других решений коммуникации с Андромедой:| | удобство | вторжение кода | взаимодействие | IPC | шина событий | маршрутизация страниц | | :---: | :-------: | :----------: |:----------: |:----------: |:----------: |:----------: | | Андромеда | хорошая | нет | хорошая | Да | Да | Нет | | DDComponentForAndroid | плохая | некоторые | плохая | Нет | Нет | Да | | ARouter | хорошая | некоторые | плохая | Нет | Нет | Да |
Добавьте classpath в buildscript (замените $version на последнюю версию):
classpath "org.qiyi.video.svg:plugin:$version"
Добавьте зависимость ядра в Application или модуль библиотеки:
implementation "org.qiyi.video.svg:core:$version"
Примените плагин Gradle в модуле приложения:
apply plugin: 'org.qiyi.svg.plugin'
Диспетчер всегда должен находиться в процессе, который живёт дольше всего, так как он управляет информацией обо всех процессах. По умолчанию основным процессом диспетчера является основной процесс, если он не настроен. Учитывая, что некоторые процессы могут жить дольше основного процесса в некоторых приложениях (например, в музыкальном приложении), разработчики должны настроить имя процесса для диспетчера в этом случае. Пример настройки в файле build.gradle модуля приложения:
dispatcher{
process ":downloader"
}
В этом случае процесс ":downloader" является процессом, который живёт дольше всего.
Добавьте код инициализации в Application.onCreate():
Andromeda.init(Context);
```## Регистрация и использование локального сервиса
### Определение и реализация локального сервиса
Есть только две разницы между локальным сервисом и обычными интерфейсами:
+ интерфейсы должны быть расположены в общем модуле, чтобы быть доступными для всех модулей
+ Andromeda будет хранить только одну реализацию за раз
### Регистрация локального сервиса
Существует два метода регистрации локального сервиса, первый из которых выглядит следующим образом:
```java
Andromeda.registerLocalService(ICheckApple.class.getCanonicalName(), new CheckApple());
Второй метод выглядит следующим образом:
Andromeda.registerLocalService(ICheckApple.class, new CheckApple());
ICheckApple — это определение интерфейса. Учитывая работу ProGuard, регистрация локального сервиса с фиксированной строкой не рекомендуется, как показано ниже:
Andromeda.registerLocalService("wang.imallen.blog.moduleexportlib.apple.ICheckApple", CheckAppleImpl.getInstance());
```### Как использовать локальный сервис
Любой модуль, находящийся в том же процессе, что и модуль сервера, может получить локальный сервис после его регистрации. Первый метод выглядит следующим образом:
```java
ICheckApple checkApple = (ICheckApple) Andromeda.getLocalService(ICheckApple.class);
Второй метод выглядит следующим образом:
ICheckApple checkApple = (ICheckApple) Andromeda.getLocalService(ICheckApple.class.getCanonicalName());
Аналогично, учитывая работу ProGuard, получение локального сервиса с фиксированной строкой также не рекомендуется:
ICheckApple checkApple = (ICheckApple) Andromeda.getLocalService("wang.imallen.blog.moduleexportlib.apple.ICheckApple");
LocalServiceDemo демонстрирует детали регистрации и использования локального сервиса.### Коллбэк локального сервиса Коллбэк локального сервиса аналогичен обычному интерфейсу и полностью зависит от разработчиков. Поэтому Andromeda не предоставляет никаких коллбэков.
Сначала определите интерфейс AIDL, а затем выведите его в общий модуль вместе со своим Stub и Proxy.
package wang.imallen.blog.moduleexportlib.apple;
import org.qiyi.video.svg.IPCCallback;
interface IBuyApple {
int buyAppleInShop(int userId);
void buyAppleOnNet(int userId, IPCCallback callback);
}
Затем предоставьте реализацию:
public class BuyAppleImpl extends IBuyApple.Stub {```markdown
### Регистрация удаленного сервиса
В отличие от регистрации локального сервиса, для регистрации удаленного сервиса требуется IBinder:
```java
Andromeda.registerRemoteService(IBuyApple.class, BuyAppleImpl.getInstance().asBinder());
Также возможен такой способ, так как BuyAppleImpl расширяет IBuyApple.Stub, который расширяет android.os.Binder:
Andromeda.registerRemoteService(IBuyApple.class, BuyAppleImpl.getInstance());
Еще один способ регистрации:
Andromeda.registerRemoteService(IBuyApple.class.getCanonicalName(), BuyAppleImpl.getInstance().asBinder());
IBinder binder = Andromeda.with(this).getRemoteService(IBuyApple.class);
if (binder == null) {
return;
}
IBuyApple buyApple = IBuyApple.Stub.asInterface(binder);
if (buyApple == null) {
return;
}
try {
buyApple.buyAppleInShop(29);
} catch (RemoteException ex) {
ex.printStackTrace();
}
Использование удаленного сервиса в android.app.Fragment, android.support.v4.app.Fragment и обычном Activity похоже, примеры можно найти в CustomFragment, CustomSupportFragment и FragActivity и т.д.Внимание: Удаленный сервис может использоваться как в одном процессе, так и в других процессах. При использовании в одном процессе он будет использоваться как локальный вызов интерфейса.
Учитывая, что затратные операции могут выполняться в процессе сервера, обратный вызов удаленного сервиса необходим. Для тех, кто требует обратного вызова, необходимо добавить параметр IPCCallback в их AIDL-определениях:
```aidl
interface IBuyApple {
int buyAppleInShop(int userId);
void buyAppleOnNet(int userId, IPCCallback callback);
}
Каноническое имя IPCCallback — org.qiyi.video.svg.IPCCallback. Его определение выглядит следующим образом:
interface IPCCallback {
void onSuccess(Bundle result);
void onFail(String reason);
}
Клиент может использовать IPCCallback следующим образом:
IBinder buyAppleBinder = Andromeda.getRemoteService(IBuyApple.class);
if (null == buyAppleBinder) {
return;
}
IBuyApple buyApple = IBuyApple.Stub.asInterface(buyAppleBinder);
if (null != buyApple) {
try {
buyApple.buyAppleOnNet(10, new IPCCallback.Stub() {
@Override
public void onSuccess(Bundle result) throws RemoteException {
...
}
``` @Override
public void onFail(String reason) throws RemoteException {
...
}
});
} catch (RemoteException ex) {
ex.printStackTrace();
}
}
Учитывая, что обратный вызов выполняется в потоке Binder, а большинство разработчиков хотят, чтобы обратный вызов выполнялся в потоке UI, Andromeda предоставляет базовый класс BaseCallback для разработчиков.
IBinder buyAppleBinder = Andromeda.getRemoteService(IBuyApple.class);
if (null == buyAppleBinder) {
return;
}
IBuyApple buyApple = IBuyApple.Stub.asInterface(buyAppleBinder);
if (null != buyApple) {
try {
buyApple.buyAppleOnNet(10, new BaseCallback() {
@Override
public void onSucceed(Bundle result) {
...
}
@Override
public void onFailed(String reason) {
...
}
});
} catch (RemoteException ex) {
ex.printStackTrace();
}
}
Рекомендуется использовать BaseCallback вместо IPCCallback! Модуль BananaActivity показывает детали о том, как им пользоваться.
Чтобы повысить приоритет работы сервера, Andromeda выполнит bindService() при вызове Andromeda.with().getRemoteService() в соответствии с жизненным циклом Fragment/Activity. В результате, требуется выполнить действие unbind при уничтожении Fragment/Activity. Существует две ситуации:
public static void unbind(Class<?> serviceClass);
public static void unbind(Set<Class<?>> serviceClasses);
Определение события в Andromeda следующее:
public class Event implements Parcelable {
private String name;
private Bundle data;
...
}
Очевидно, событие состоит из имени и данных, которые являются типом Bundle, который может загружать параметры примитивного типа или параметры типа Parcelable.
Подписка на событие очень проста для тех, кто реализует EventListener, например, для MainActivity:
Andromeda.subscribe(EventConstants.APPLE_EVENT, MainActivity.this);
Это означает, что подписывается на событие, имя которого равно EventConstants.APPLE_EVENT.
Публикация события также проста:
Bundle bundle = new Bundle();
bundle.putString("Result", "gave u five apples!");
Andromeda.publish(new Event(EventConstants.APPLE_EVENT, bundle));
После публикации все слушатели в любых процессах смогут получить это событие.
MainActivity показывает детали о том, как подписываться и публиковать события.
BSD-3-Clause. Подробности см. в файле BSD-3-Clause.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )