Cartrofit — это набор аннотаций для создания интерпретатора, который может быть расширен в среде выполнения Android. Интерпретатор работает с шаблонами кода, подобно Retrofit.
В настоящее время интерпретатор поддерживает доступ к CarPropertyService и широковещательную рассылку в Android, но приложение также может расширять основные библиотеки для реализации других функций.
Обычно функции, которые можно расширить, должны соответствовать следующему требованию: они должны иметь возможность получать доступ к неограниченным ресурсам через ограниченный интерфейс.
Структура проекта
Сначала необходимо объявить библиотеку jitpack в корневом каталоге:
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}
Затем следует указать основной каталог, где находится ядро фреймворка. Если требуется расширить другие функции, этот каталог должен быть указан как зависимость в build.gradle используемого модуля:
implementation 'com.gitee.li-yangbin.cartrofit:core:latest-version'
Также необходимо указать каталоги, содержащие расширения для доступа к CarProperty и отправки/получения широковещательных сообщений:
implementation 'com.gitee.li-yangbin.cartrofit:carproperty:latest-version'
implementation 'com.gitee.li-yangbin.cartrofit:broadcast:latest-version'
Кроме того, следует добавить каталог с библиотекой обработки аннотаций, которая используется в рамках фреймворка:
annotationProcessor 'com.gitee.li-yangbin.cartrofit:processorlib:latest-version'
Каталог hvacDemo содержит модифицированный код приложения для автомобильной системы HVAC (климат-контроль), который служит для тестирования и демонстрации. Этот код не является обязательным и предоставляется только для справки.
Интерфейс CarProperty
Для объявления бизнес-интерфейса (на примере доступа к CarHvacManager) используется аннотация @CarPropertyScope:
@CarPropertyScope(Car.HVAC_SERVICE)
public interface HvacPanelApi {
/**
* Интерфейс объявления
*/
}
Перед использованием необходимо инициализировать Cartrofit в классе Application:
Cartrofit.register(new HvacContext(this));
Здесь HvacContext — это встроенный класс, поддерживающий доступ к Android Automotive HVAC. Приложение должно учитывать свои потребности при расширении этого класса.
Чтобы использовать интерфейс, можно применить динамический прокси Java для получения его реализации:
HvacPanelApi hvacApi = Cartrofit.from(HvacPanelApi.class);
Использование Set и Get
С помощью аннотаций Set и Get можно получить доступ к свойствам CarHvacManager, что эквивалентно методам setProperty и getProperty:
@Set(propId = CarHvacManager.ID_ZONED_TEMP_SETPOINT, area = DRIVER_ZONE_ID)
void setDriverTemperature(int temperature);
@Get(propId = CarHvacManager.ID_ZONED_TEMP_SETPOINT, area = DRIVER_ZONE_ID)
int getDriverTemperature();
Эти два метода эквивалентны следующим вызовам:
CarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT, DRIVER_ZONE_ID, temperature)
CarHvacManager.getIntProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT, DRIVER_ZONE_ID);
Отслеживание изменений
Используя аннотацию Track, можно подписаться на уведомления об изменениях свойств CarHvacManager:
@Track(id = CarHvacManager.ID_ZONED_TEMP_SETPOINT, area = HvacPanelApi.DRIVER_ZONE_ID)
Flow<Integer> trackDriverTemperature();
Flow — это встроенный тип наблюдаемого источника данных в фреймворке. Кроме него, Cartrofit поддерживает RxJava, DataBinding и LiveData (необходимо добавить соответствующие конфигурации в build.gradle).
Пример использования RxJava:
@Track(id = CarHvacManager.ID_ZONED_TEMP_SETPOINT, area = HvacPanelApi.PASSENGER_ZONE_ID)
Observable<Integer> trackPassengerTemperature();
Пример использования DataBinding:
@Track(id = CarHvacManager.ID_ZONED_AC_ON, area = SEAT_ALL, sticky = StickyType.ON)
ObservableBoolean trackACState();
Пример использования LiveData:
@Track(id = CarHvacManager.ID_WINDOW_DEFROSTER_ON, area = VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, sticky = StickyType.ON)
LiveData<Boolean> trackRearDefrosterState();
Регистрация обратных вызовов
Аннотацию Register можно использовать для автоматического преобразования источников данных (Observable, Flow, LiveData) в зарегистрированные интерфейсы обратного вызова:
@Register
void registerWarmChangeCallback(@Callback OnWarmLevelChangeCallback callback);
interface OnWarmLevelChangeCallback {
@Track(propId = CarHvacManager.ID_ZONED_SEAT_TEMP, area = HvacPanelApi.DRIVER_ZONE_ID)
void onDriverLevelChange(int level);
@Track(propId = CarHvacManager.ID_ZONED_SEAT_TEMP, area = HvacPanelApi.PASSENGER_ZONE_ID)
void onPassengerLevelChange(int level);
}
Метод registerWarmChangeCallback регистрирует обратный вызов для изменения уровня нагрева сиденья. Callback-аннотация определяет тип обратного вызова OnWarmLevelChangeCallback, который настраивается пользователем. Методы onDriverLevelChange и onPassengerLevelChange представляют собой обратные вызовы для изменения температуры на стороне водителя и пассажира соответственно.
Если нужно зарегистрировать только один обратный вызов для свойства, то аннотацию Register можно опустить:
@Track(propId = CarHvacManager.ID_ZONED_FAN_DIRECTION, area = HvacPanelApi.SEAT_ALL)
void trackFanDirection(@Callback OnDanDirectionChangCallback callback); **1. Отправка**
Чтобы отправить широковещательное сообщение, используйте аннотацию Send и передайте в неё параметр action со значением «action.test».
Добавьте в код:
```java
@Broadcast(isLocal = true)
@Process
public interface TestLocalBroadcast {
@Send(action = "action.test")
void sendTestAction();
}
Вызов интерфейса sendTestAction() эквивалентен вызову следующего кода Java:
Intent intent = new Intent("action.test");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Помимо установки действия Action, аннотация Send также поддерживает установку других параметров, таких как packageName, className и т. д. (см. код на сайте gitee.com/li-yangbin/cartrofit/blob/master/broadcast/src/main/java/com/liyangbin/cartrofit/broadcast/Send.java).
2. Получение
Используйте аннотацию Receive для прослушивания широковещательных сообщений. Добавьте в код:
@Broadcast
public interface TimeTickerApi {
@Receive(action = Intent.ACTION_TIME_TICK)
void registerTimeTickListener(Runnable action);
}
Вызов метода registerTimeTickListener() эквивалентен следующему коду Java:
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
}, new IntentFilter(Intent.ACTION_TIME_TICK));
Кроме установки действия action, аннотация Receive также поддерживает другие параметры (см. код на сайте gitee.com/li-yangbin/cartrofit/blob/master/broadcast/src/main/java/com/liyangbin/cartrofit/broadcast/Receive.java).
3. Использование аннотации Register с Receive
Для одновременного прослушивания нескольких широковещательных сообщений используйте аннотацию Register вместе с Receive. Добавьте в код:
@Broadcast
public interface TimeTickerApi {
@Register
void registerTimeChangeListener(@Callback TimeChangeListener listener);
}
interface TimeChangeListener {
@Receive(action = Intent.ACTION_TIME_TICK)
void onTimeTick();
@Receive(action = Intent.ACTION_TIMEZONE_CHANGED)
void onTimeZoneChange(@Extra(key = "time-zone") String zoneId);
}
Вызовы методов registerTimeTickListener() и registerTimeChangeListener() эквивалентны следующему коду Java:
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_TIME_TICK.equals(action)) {
// onTimeTick 时间变化
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
String zoneId = intent.getStringExtra("time-zone");
// onTimeZoneChange 时区变化
}
}
}, filter);
Обратите внимание на использование аннотации Extra. В интерфейсе обратного вызова она соответствует полю extra в методе onReceive().
4. Отмена регистрации с помощью Unregister
Чтобы отменить регистрацию широковещательного сообщения, используйте аннотацию Unregister. Добавьте в код:
@Broadcast
@Process
public interface TimeTickerApi {
@Register
void registerTimeChangeListener(@Callback TimeChangeListener listener);
@Unregister(TimeTickerApiId.registerTimeChangeListener)
void unregisterTimeChangeListener(TimeChangeListener listener);
}
Здесь TimeTickerApiId.registerTimeChangeListener — это идентификатор, который генерируется автоматически. Для этого необходимо добавить processorLib в файл build.gradle и объявить аннотацию Process в начале бизнес-интерфейса. После этого нужно выполнить сборку проекта.
После отмены регистрации всех слушателей TimeChangeListener фреймворк отменит регистрацию внутреннего приёмника широковещательных сообщений (BroadcastReceiver). Поэтому приложение должно самостоятельно отменить регистрацию в зависимости от ситуации, чтобы предотвратить утечку памяти.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )