1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/bettar-Andromeda

Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Андромеда

Андромеда_лицензия Андромеда_ядро_тег Андромеда_плагин_тег

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

Примечание: причина, которая отличает локальные сервисы от удаленных, заключается в том, что типы параметров в удаленных сервисах могут быть только примитивными типами или пользовательскими типами, реализующими 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());

Использование удаленного сервиса

  • перед получением удаленного сервиса необходимо вызвать with(), так как Andromeda требует установки приоритета процесса сервера в соответствии с жизненным циклом Fragment/Activity;
  • getRemoteService() вернет IBinder. Затем можно получить прокси с помощью XXStub.asInterface(binder);Пример использования в FragmentActivity:
        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. Существует две ситуации:

  • Для тех, кто получает удалённый сервис с использованием Fragment/Activity и в основном потоке, Andromeda выполнит действие unbind автоматически+ Для тех, кто получает сервисы не с использованием Fragment/Activity или в рабочем потоке, действие unbind должно быть выполнено разработчиками:
    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.

Поддержка

  1. Примеры кода
  2. Wiki и часто задаваемые вопросы
  3. Связаться по адресу bettarwang@gmail.com

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Компонентная коммуникационная структура, подходящая для многопроцессной архитектуры. Развернуть Свернуть
BSD-3-Clause
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/bettar-Andromeda.git
git@api.gitlife.ru:oschina-mirror/bettar-Andromeda.git
oschina-mirror
bettar-Andromeda
bettar-Andromeda
master