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

OSCHINA-MIRROR/bettar-Andromeda

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку 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'

Как использовать

Конфигурирование Dispatcher

Dispatcher всегда должен находиться в процессе, который живёт дольше всего, поскольку он управляет информацией обо всех процессах. По умолчанию процесс Dispatcher — это главный процесс, если конфигурация отсутствует. Учитывая, что некоторые процессы могут жить дольше главного процесса (например, музыкальный проигрыватель), разработчики должны указывать имя процесса для Dispatcher в этом случае. Пример конфигурации в build.gradle модуля приложения:

dispatcher{
    process ":downloader"
}

В этом случае процесс ":downloader" является процессом, который живёт дольше всего.

Инициализация

Добавьте код инициализации в метод onCreate() класса Application:

Andromeda.init(Context);

Регистрация и использование локального сервиса

Определение и реализация локального сервиса

Основные различия между локальным сервисом и обычными интерфейсами следующие:

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

Регистрация локального сервиса

Регистрация локального сервиса возможна двумя способами:

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());

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

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

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 показывает детали регистрации и использования локального сервиса.

Обратный вызов локального сервиса

Обратный вызов локального сервиса аналогичен обычному интерфейсу, поэтому всё зависит от разработчиков. Итак, Андромеда не предоставляет никаких обратных вызовов.

Регистрация и использование удалённого сервиса

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

Сначала определяйте 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 {

    private static BuyAppleImpl instance;

    public static BuyAppleImpl getInstance() {
        if (null == instance) {
            synchronized (BuyAppleImpl.class) {
                if (null == instance) {
                    instance = new BuyAppleImpl();
                }
            }
        }
        return instance;
    }

    private BuyAppleImpl() {}

    @Override
    public int buyAppleInShop(int userId) throws RemoteException {
        ...
    }

    @Override
    public void buyAppleOnNet(int userId, IPCCallback callback) throws RemoteException {
        ...
    }
}

Регистрация удалённого сервиса

В отличие от регистрации локального сервиса, IBinder удалённого сервиса необходим для регистрации:

Andromeda.registerRemoteService(IBuyApple.class, BuyAppleImpl.getInstance().asBinder());

Также можно использовать другой способ:

Andromeda.registerRemoteService(IBuyApple.class, BuyAppleImpl.getInstance());

Ещё один способ регистрации:

Andromeda.registerRemoteService(IBuyApple.class.getCanonicalName(), BuyAppleImpl.getInstance().asBinder());

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

  • перед получением удалённого сервиса необходимо использовать метод with(), поскольку Андромеда должна управлять приоритетами процессов согласно жизненному циклу 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:

interface IBuyApple {
    int buyAppleInShop(int userId);
    void buyAppleOnNet(int userId, IPCCallback callback);
}

Каноническое имя IPCCallback — это org.qiyi.video.svg.IPCCallback. Его определение такое:

interface IPCCallback {
    void onSuccess(in 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, Андромеда предлагает базовый класс 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 и часто задаваемые вопросы (FAQ)
  3. Обратиться по адресу bettarwang@gmail.com

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

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

Введение

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

Обновления

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

Участники

все

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

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