沧州北京网站建设如何在网站后台备份数据库表

diannao/2026/1/25 7:30:01/文章来源:
沧州北京网站建设,如何在网站后台备份数据库表,温州网站建设报价,网站建设 需求确认书前言 关于 Android 车机#xff0c;之前分析过方控上自定义按键的输入机制和中控上旋钮输入的原理#xff0c;但都局限于 Car Service 内 Input 相关模块。 一文了解 Android 车机如何处理中控的旋钮输入从实体按键看 Android 车载的自定义事件机制 本文将结合 Android 系… 前言 关于 Android 车机之前分析过方控上自定义按键的输入机制和中控上旋钮输入的原理但都局限于 Car Service 内 Input 相关模块。 一文了解 Android 车机如何处理中控的旋钮输入从实体按键看 Android 车载的自定义事件机制 本文将结合 Android 系统整体对 CarService 的构成和链路对其做一个全面的分析和理解。 目录 构成 CarServiceHelperService 系统服务CarService 核心服务 App builtin appupdatable app Car 专用 APICar Apps CarService 启动链路 Service 整体CarInputService 输入服务CarPropertyService 属性服务 Vehicle 属性调用链路 Car 获取CarPropertyManager 调用 总结 构成 1. CarServiceHelperService 系统服务 SystemServer 中专门为了 Automotive OS 设立的系统服务用来管理车机的核心服务 CarService。该系统服务的具体实现实际上由 CarServiceHelperServiceUpdatableImpl 类完成后面会提到。 System service side companion service for CarService. Starts car service and provide necessary API for CarService. Only for car product. 2. CarService 核心服务 App Car Service App 实际上分为两个一个是和系统服务直接交互的 builtin app另一个是给该 built app 提供实际实现的 updatable app。 builtin app 系统中与车相关的核心 App掌管最重要的 CarService 服务类。目录位于 packages/services/Car/service-builtin/ 其 AndroidManifest.xml 文件如下可以看到它具有系统权限、与 system uid 共享数据。 manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:androidprvhttp://schemas.android.com/apk/prv/res/androidpackagecom.android.carcoreApptrueandroid:sharedUserIdandroid.uid.systemapplication android:labelstring/app_titleandroid:directBootAwaretrueandroid:allowBackupfalseandroid:persistenttrueservice android:name.CarServiceandroid:singleUsertrueandroid:exportedtrueintent-filteraction android:nameandroid.car.ICar//intent-filter/service.../application /manifestupdatable app builtin app 的所有具体实现以及后续支持的一堆服务都在 updatable app 中实现目录见 packages/services/Car/service/ 其 AndroidManifest.xml 文件如下可以看到它也具有系统权限。 manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:androidprvhttp://schemas.android.com/apk/prv/res/androidpackagecom.android.car.updatablecoreApptruepermission-group android:nameandroid.car.permission-group.CAR_MONITORINGandroid:icondrawable/perm_group_carandroid:descriptionstring/car_permission_descandroid:labelstring/car_permission_label/...application android:labelstring/app_titleandroid:directBootAwaretrueandroid:allowBackupfalse/application /manifest3. Car 专用 API Android 车机里提供给系统使用汽车相关能力的专用接口源码实现在 packages/services/Car/car-lib/ 看下它的 manifest 文件 manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:androidprvhttp://schemas.android.com/apk/prv/res/androidpackageandroid.car uses-sdk android:minSdkVersion23 android:targetSdkVersion23 / /manifest再看下它的 bp 文件 ... filegroup {name: android.car-full-src,srcs: [src/**/*.java,src/**/*.aidl,],visibility: [//packages/services/Car/car-lib,//packages/services/Car/car-lib-module,], }java_library {name: android.car,srcs: [:android.car-full-src,],aidl: {include_dirs: [packages/modules/Bluetooth/framework/aidl-export,],},libs: [android.car.builtin,framework-annotations-lib,modules-utils-preconditions,framework-wifi,framework-bluetooth,],installable: true,sdk_version: module_current, }可以看到它会编译到 android.car.jar 中而非面向 AOSP 手机/平板的 android.jar 中。这也意味着如果要基于 Car 相关 API 开发需要通过添加 Automotive os addon 的方式才能导入该 SDK。 这个 jar 囊括了我们常用的 Car、CarPowerManager、CarSettings 等下面罗列了部分常用的 Car API android.car包含了与车相关的基本API。例如车辆后视镜门座位窗口等 menu车辆应用菜单相关API cluster仪表盘相关API diagnostic包含与汽车诊断相关的API。 hardware车辆硬件相关API cabin座舱相关API hvac通风空调相关API。hvac是Heating, ventilation and air conditioning的缩写 property属性相关API radio收音机相关API input输入相关API media多媒体相关API navigation导航相关API settings设置相关API vms汽车监测相关API … 最后的实现会经由 AIDL 抵达上个章节的 CarService App。 4. Car Apps 提供 Automotive OS 内置的、专门为 Car 场景设计的 App目录位于 packages/apps/Car/ 比如面向 Car 的 SystemUI、Launcher、Settings、IME 等。 CarService 启动链路 Service 整体 SystemServer 会在启动系统服务的过程中依据 FEATURE_AUTOMOTIVE 的特性决定是否启动 AAOS 的系统服务 CarServiceHelperService。 public final class SystemServer implements Dumpable {...private static final String CAR_SERVICE_HELPER_SERVICE_CLASS com.android.internal.car.CarServiceHelperService;private void startOtherServices(NonNull TimingsTraceAndSlog t) {t.traceBegin(startOtherServices);...mActivityManagerService.systemReady(() - {Slog.i(TAG, Making services ready);...boolean isAutomotive mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);if (isAutomotive) {t.traceBegin(StartCarServiceHelperService);final SystemService cshs mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);t.traceEnd();}...}, t);...}... }CarServiceHelperService 执行 onStart() 的时候会将后续的工作交给 CarServiceHelperServiceUpdatableImpl 来处理。 其 onStart() 里调用 bindService() 绑定 action 为 “android.car.ICar”、package 为 “com.android.car” 的 Service即构成章节里提到的 CarService 组件。 public class CarServiceHelperService extends SystemServiceimplements Dumpable, DevicePolicySafetyChecker, CarServiceHelperInterface {...Overridepublic void onStart() {...mCarServiceHelperServiceUpdatable.onStart();}... }public final class CommonConstants {...// CarService Constantspublic static final String CAR_SERVICE_INTERFACE android.car.ICar;... }public final class CarServiceHelperServiceUpdatableImplimplements CarServiceHelperServiceUpdatable, Executor {...private static final String CAR_SERVICE_PACKAGE com.android.car;Overridepublic void onStart() {Intent intent new Intent(CAR_SERVICE_INTERFACE).setPackage(CAR_SERVICE_PACKAGE);Context userContext mContext.createContextAsUser(UserHandle.SYSTEM, /* flags */ 0);if (!userContext.bindService(intent, Context.BIND_AUTO_CREATE, this,mCarServiceConnection)) {Slogf.wtf(TAG, cannot start car service);}}... }CarService 的实现都在父类 ServiceProxy 中比如首先被调用的 onCreate()内部将先调用 init()。 init() 将构建 mRealServiceClassName 的实例而 mRealServiceClassName 变量来自于 UpdatablePackageDependency.java 中定义的 CAR_SERVICE_IMPL_CLASS 常量即 “com.android.car.CarServiceImpl”。 通过如下代码看到这意味着将初始化 CarServiceImpl 实例。 public class CarService extends ServiceProxy {...public CarService() {super(UpdatablePackageDependency.CAR_SERVICE_IMPL_CLASS);// Increase the number of binder threads in car serviceBinderInternal.setMaxThreads(MAX_BINDER_THREADS);}... }public class ServiceProxy extends Service {...Overridepublic void onCreate() {init();mRealService.onCreate();}private void init() {mUpdatablePackageContext UpdatablePackageContext.create(this);try {mRealServiceClass mUpdatablePackageContext.getClassLoader().loadClass(mRealServiceClassName);// Use default constructor alwaysConstructor constructor mRealServiceClass.getConstructor();mRealService (ProxiedService) constructor.newInstance();mRealService.doAttachBaseContext(mUpdatablePackageContext);mRealService.setBuiltinPackageContext(this);} catch (Exception e) {throw new RuntimeException(Cannot load class: mRealServiceClassName, e);}}... }public class UpdatablePackageDependency {/** {code com.android.car.CarServiceImpl} class */public static final String CAR_SERVICE_IMPL_CLASS com.android.car.CarServiceImpl;... }init() 之后是执行创建出来的 CarServiceImpl 实例的 onCreate()可以看到是继续创建关键类 ICarImpl 的实例并再次执行 init()。 public class CarServiceImpl extends ProxiedService {...Overridepublic void onCreate() {...mICarImpl new ICarImpl(this,getBuiltinPackageContext(),mVehicle,SystemInterface.Builder.defaultSystemInterface(this).build(),mVehicleInterfaceName);mICarImpl.init();...}... }public class ICarImpl extends ICar.Stub {...ICarImpl( ... ) {...mHal constructWithTrace(t, VehicleHal.class,() - new VehicleHal(serviceContext, vehicle));...mCarPropertyService constructWithTrace(t, CarPropertyService.class,() - new CarPropertyService(serviceContext, mHal.getPropertyHal()));mCarDrivingStateService constructWithTrace(t, CarDrivingStateService.class,() - new CarDrivingStateService(serviceContext, mCarPropertyService));...mCarPowerManagementService constructWithTrace(t, CarPowerManagementService.class,() - new CarPowerManagementService(mContext, mHal.getPowerHal(),systemInterface, mCarUserService, powerPolicyDaemon));...mCarInputService constructWithTrace(t, CarInputService.class,() - new CarInputService(serviceContext, mHal.getInputHal(), mCarUserService,mCarOccupantZoneService, mCarBluetoothService));...ListCarServiceBase allServices new ArrayList();allServices.add(mCarPropertyService); // mCarUXRestrictionsService depends on itallServices.add(mCarPowerManagementService);allServices.add(mCarDrivingStateService);allServices.add(mCarInputService);......mAllServices allServices.toArray(new CarServiceBase[allServices.size()]);mICarSystemServerClientImpl new ICarSystemServerClientImpl();...}... }ICarImpl 的初始化将完成很多 vehicle 相关的重要工作 将初始化和 vehicle HAL 层交互的 VehicleHal 实例遍历 ICarImpl 实例构造时候创建的各个扩展自 CarServiceBase 的实例逐个调用 init() 初始化比如 掌管车辆硬件按键输入的 CarInputService掌管车辆属性的 CarPropertyService掌管车辆电源管理的 CarPowerManagementService掌管车辆驾驶状态的 CarDrivingStateService等等 public class ICarImpl extends ICar.Stub {...void init() {...mHal.init();for (CarServiceBase service : mAllServices) {service.init();}...}... }下面以 CarInputService 和 CarPropertyService 为例继续看某个具体的 CarServiceBase 初始化了什么。 CarInputService 输入服务 CarInputService 初始化是向和 VehicleHal 交互的 InputHalService 传递输入相关的监听器 Listener。 public class CarInputService ... {...Overridepublic void init() {if (!mInputHalService.isKeyInputSupported()) {return;}mInputHalService.setInputListener(this);...}... }InputHalService 将依据是否支持按键输入、旋钮输入、自定义输入的配置决定是否向 VehicleHal 订阅 Input Property 变化。 public class InputHalService extends HalServiceBase {...private final VehicleHal mHal;public void setInputListener(InputListener listener) {boolean keyInputSupported;boolean rotaryInputSupported;boolean customInputSupported;synchronized (mLock) {if (!mKeyInputSupported !mRotaryInputSupported !mCustomInputSupported) {Slogf.w(TAG, input listener set while rotary and key input not supported);return;}mListener listener;keyInputSupported mKeyInputSupported;rotaryInputSupported mRotaryInputSupported;customInputSupported mCustomInputSupported;}if (keyInputSupported) {mHal.subscribeProperty(this, HW_KEY_INPUT);}if (rotaryInputSupported) {mHal.subscribeProperty(this, HW_ROTARY_INPUT);}if (customInputSupported) {mHal.subscribeProperty(this, HW_CUSTOM_INPUT);}}... }CarPropertyService 属性服务 CarPropertyService 也是一样向和 VehicleHal 打交道的 PropertyHalService 传递输入相关的监听器 Listener。 public class CarPropertyService extends ICarProperty.Stubimplements CarServiceBase, PropertyHalService.PropertyHalListener {Overridepublic void init() {synchronized (mLock) {// Cache the configs list and permissions to avoid subsequent binder callsmConfigs mHal.getPropertyList();mPropToPermission mHal.getPermissionsForAllProperties();if (DBG) {Slogf.d(TAG, cache CarPropertyConfigs mConfigs.size());}}mHal.setListener(this);}... }PropertyHalService 将 CarPropertyService 作为 Callback 暂存等待来自 HAL 的 Vehicle Property 变化回调。 public class PropertyHalService extends HalServiceBase {/*** Set the listener for the HAL service* param listener*/public void setListener(PropertyHalListener listener) {synchronized (mLock) {mListener listener;}}... }Vehicle 属性调用链路 Car 获取链路 对于其他 App 来说想要使用 Car API得做些准备工作 先获取 Car 实例然后执行连接成功之后获取具体功能的 Manager 实例 比如这段用 CarPropertyManager 的示例 private Car mCar;private CarPropertyManager mCarPropertyManager;mCar Car.createCar(this, /* handler */ null, Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER,(car, ready) - {mCar car;if (ready) {mCarPropertyManager (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);...}});我们结合源码看下上面这个步骤的链路 createCar() 首先检查当前 OS 是否属于 Automotive 版本之后调用 Car 构造函数进行一些全局变量的准备。 public final class Car {...public static Car createCar(Context context, ServiceConnection serviceConnectionListener,Nullable Handler handler) {if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {Log.e(TAG_CAR, FEATURE_AUTOMOTIVE not declared while android.car is used);return null;}try {return new Car(context, /* service */ null , serviceConnectionListener,/* statusChangeListener */ null, handler);} catch (IllegalArgumentException e) {// Expected when car service loader is not available.}return null;}private Car( ... ) {mContext context;mEventHandler determineEventHandler(handler);mMainThreadEventHandler determineMainThreadEventHandler(mEventHandler);mService service;if (service ! null) {mConnectionState STATE_CONNECTED;} else {mConnectionState STATE_DISCONNECTED;}mServiceConnectionListenerClient serviceConnectionListener;mStatusChangeCallback statusChangeListener;// Store construction stack so that client can get help when it crashes when car service// crashes.if (serviceConnectionListener null statusChangeListener null) {mConstructionStack new RuntimeException();} else {mConstructionStack null;}}... }connect() 首先检查是否重复请求连接了确实需要连接的话调用 startCarService() 核心处理。 startCarService() 将绑定 CarService 服务。 public final class Car {...public void connect() throws IllegalStateException {synchronized (mLock) {if (mConnectionState ! STATE_DISCONNECTED) {throw new IllegalStateException(already connected or connecting);}mConnectionState STATE_CONNECTING;startCarService();}}private void startCarService() {Intent intent new Intent();intent.setPackage(CAR_SERVICE_PACKAGE);intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME);boolean bound mContext.bindService(intent, mServiceConnectionListener,Context.BIND_AUTO_CREATE);synchronized (mLock) {if (!bound) {mConnectionRetryCount;if (mConnectionRetryCount CAR_SERVICE_BIND_MAX_RETRY) {Log.w(TAG_CAR, cannot bind to car service after max retry);mMainThreadEventHandler.post(mConnectionRetryFailedRunnable);} else {mEventHandler.postDelayed(mConnectionRetryRunnable,CAR_SERVICE_BIND_RETRY_INTERVAL_MS);}} else {mEventHandler.removeCallbacks(mConnectionRetryRunnable);mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);mConnectionRetryCount 0;mServiceBound true;}}} ... }绑定成功之后将 ICar AIDL 的本地接口代理赋值到 mService 变量server 端在 CarService 的 ICarImpl 中待使用。 public final class Car {...private final ServiceConnection mServiceConnectionListener new ServiceConnection() {Overridepublic void onServiceConnected(ComponentName name, IBinder service) {synchronized (mLock) {ICar newService ICar.Stub.asInterface(service);if (mService ! null mService.asBinder().equals(newService.asBinder())) {// already connected.return;}mConnectionState STATE_CONNECTED;mService newService;}if (mStatusChangeCallback ! null) {mStatusChangeCallback.onLifecycleChanged(Car.this, true);} else if (mServiceConnectionListenerClient ! null) {mServiceConnectionListenerClient.onServiceConnected(name, service);}}Overridepublic void onServiceDisconnected(ComponentName name) {...};... }getCarManager() 首先得确保 CarService 准备就绪了然后再去缓存 Manager 实例的 HashMap mServiceMap 中查找是否已有现成的最后才发起 AIDL 获取该功能的接口。 public final class Car {...private final HashMapString, CarManagerBase mServiceMap new HashMap();public Object getCarManager(String serviceName) {CarManagerBase manager;synchronized (mLock) {if (mService null) {Log.w(TAG_CAR, getCarManager not working while car service not ready);return null;}manager mServiceMap.get(serviceName);if (manager null) {try {IBinder binder mService.getCarService(serviceName);if (binder null) {Log.w(TAG_CAR, getCarManager could not get binder for service: serviceName);return null;}manager createCarManagerLocked(serviceName, binder);if (manager null) {Log.w(TAG_CAR, getCarManager could not create manager for service: serviceName);return null;}mServiceMap.put(serviceName, manager);} catch (RemoteException e) {handleRemoteExceptionFromCarService(e);}}}return manager;}... }ICarImpl 则是依据约定好的 Manager 的 Service 端名称去 CarService 中返回启动时候创建的一堆具体服务。 比如PROPERTY_SERVICE 的话返回 CarPropertyServiceCAR_INPUT_SERVICE 返回 CarInputService。 public class ICarImpl extends ICar.Stub {...public IBinder getCarService(String serviceName) {if (!mFeatureController.isFeatureEnabled(serviceName)) {Slogf.w(CarLog.TAG_SERVICE, getCarService for disabled service: serviceName);return null;}switch (serviceName) {...case Car.PROPERTY_SERVICE:case Car.SENSOR_SERVICE:case Car.VENDOR_EXTENSION_SERVICE:return mCarPropertyService;...case Car.CAR_INPUT_SERVICE:return mCarInputService;...default:IBinder service null;if (mCarExperimentalFeatureServiceController ! null) {service mCarExperimentalFeatureServiceController.getCarService(serviceName);}if (service null) {Slogf.w(CarLog.TAG_SERVICE, getCarService for unknown service: serviceName);}return service;}}... }CarPropertyManager 调用链路 Automotive OS 提供了 CarPropertyManager API 给第三方 App 读写车辆属性。参数 propId 来自于 VehiclePropertyIds 类中定义的属性 ID当然也需要获得相应的 permission。 比如读写车窗属性的 ID 为 WINDOW_POS需要 android.car.permission.CONTROL_CAR_WINDOWS 的权限。 读取 getProperty() 首先调用 checkSupportedProperty() 检查是否支持该属性如果是 USER 相关的属性会抛出如下的异常 Unsupported property:xxx 通过检查的向实现的 Service 发出读取调用。 public class CarPropertyManager extends CarManagerBase {public E CarPropertyValueE getProperty(NonNull ClassE clazz, int propId, int areaId) {checkSupportedProperty(propId);try {CarPropertyValueE propVal mService.getProperty(propId, areaId);if (propVal ! null propVal.getValue() ! null) {Class? actualClass propVal.getValue().getClass();}return propVal;}...}private void checkSupportedProperty(int propId) {switch (propId) {case VehiclePropertyIds.INITIAL_USER_INFO:case VehiclePropertyIds.SWITCH_USER:case VehiclePropertyIds.CREATE_USER:case VehiclePropertyIds.REMOVE_USER:case VehiclePropertyIds.USER_IDENTIFICATION_ASSOCIATION:throw new IllegalArgumentException(Unsupported property: VehiclePropertyIds.toString(propId) ( propId ));}}... }ICarProperty aidl 的实现即位于上个章节分析到的 CarPropertyService 中。 先到存放所有 Property ID 的 SparseArray 中检查是否确实存在该 Property如果不存在的话打印 error 提醒并结束 获取该 Property 的 Permission 配置如果不存在的话抛出如下异常 SecurityException: Platform does not have permission to read value for property Id: 0x… assertPermission() 检查当前 Car Service 是否确实被授予了如上 Permission 最后调用持有的 PropertyHalService 继续发出读取的调用 public class CarPropertyService extends ICarProperty.Stubimplements CarServiceBase, PropertyHalService.PropertyHalListener {Overridepublic CarPropertyValue getProperty(int prop, int zone) ... {synchronized (mLock) {if (mConfigs.get(prop) null) {// Do not attempt to register an invalid propIdSlogf.e(TAG, getProperty: propId is not in config list:0x toHexString(prop));return null;}}// Checks if android has permission to read property.String permission mHal.getReadPermission(prop);if (permission null) {throw new SecurityException(Platform does not have permission to read value for property Id: 0x Integer.toHexString(prop));}CarServiceUtils.assertPermission(mContext, permission);return runSyncOperationCheckLimit(() - {return mHal.getProperty(prop, zone);});}... }PropertyHalService 首先调用 managerToHalPropId() 将 Property ID 转为 HAL 中该 ID 的定义并再度检查该 HAL ID 是否确实存在。如果不存在的话亦抛出异常 IllegalArgumentExceptionInvalid property Id : 0x… 接着通过 VehicleHal 传递 HAL 中 ID 继续读取得到 HalPropValue当读取的 value 存在的话首先得获取该 Property 在 HAL 层和上层定义的 HalPropConfig 规则。 最后依据 config 将 value 解析成 CarPropertyValue 类型返回。 public class PropertyHalService extends HalServiceBase { / ...public CarPropertyValue getProperty(int mgrPropId, int areaId)throws IllegalArgumentException, ServiceSpecificException {int halPropId managerToHalPropId(mgrPropId);if (!isPropertySupportedInVehicle(halPropId)) {throw new IllegalArgumentException(Invalid property Id : 0x toHexString(mgrPropId));}// CarPropertyManager catches and rethrows exception, no need to handle here.HalPropValue value mVehicleHal.get(halPropId, areaId);if (value null) {return null;}HalPropConfig propConfig;synchronized (mLock) {propConfig mHalPropIdToPropConfig.get(halPropId);}return value.toCarPropertyValue(mgrPropId, propConfig);}... }其实 VehicleHal 并未做太多处理就直接交给了 HalClient 来处理。 public class VehicleHal implements HalClientCallback {...public HalPropValue get(int propertyId)throws IllegalArgumentException, ServiceSpecificException {return get(propertyId, NO_AREA);}...public HalPropValue get(int propertyId, int areaId)throws IllegalArgumentException, ServiceSpecificException {return mHalClient.getValue(mPropValueBuilder.build(propertyId, areaId));}... }HalClient 通过 invokeRetriable() 进行超时为 50ms 的 internalGet() 调用如果结果是 TRY_AGAIN 并且尚未超时的话再次调用反之已经超时或者结果成功获取到的话即结束。 后续会再次检查该 Result 中的 status是否是不合法的、空的值等等通过检查的话则返回 HalPropValue 出去。 final class HalClient {...private static final int SLEEP_BETWEEN_RETRIABLE_INVOKES_MS 50;HalPropValue getValue(HalPropValue requestedPropValue)throws IllegalArgumentException, ServiceSpecificException {ObjectWrapperValueResult resultWrapper new ObjectWrapper();resultWrapper.object new ValueResult();int status invokeRetriable(() - {resultWrapper.object internalGet(requestedPropValue);return resultWrapper.object.status;}, mWaitCapMs, mSleepMs);ValueResult result resultWrapper.object;if (StatusCode.INVALID_ARG status) {throw new IllegalArgumentException(getValueErrorMessage(get, requestedPropValue, result.errorMsg));}if (StatusCode.OK ! status || result.propValue null) {if (StatusCode.OK status) {status StatusCode.NOT_AVAILABLE;}throw new ServiceSpecificException(status, getValueErrorMessage(get, requestedPropValue, result.errorMsg));}return result.propValue;}private ValueResult internalGet(HalPropValue requestedPropValue) {final ValueResult result new ValueResult();try {result.propValue mVehicle.get(requestedPropValue);result.status StatusCode.OK;result.errorMsg new String();}...return result;}... }internalGet() 的实现由持有的 VehicleStub 实例的 get 方法完成其实现对应于依据 HIDL 的配置调用 HAL 侧获取相应数据。 public abstract class VehicleStub {...Nullablepublic abstract HalPropValue get(HalPropValue requestedPropValue)throws RemoteException, ServiceSpecificException;... }set 写入的链路和 get 大同小异后面我会以车窗状态和开关操作为例详细展开车辆属性 API 的使用和原理细节。 总结 我们通过一张表格来总结 CarService 相关组件的构成。 Car 相关组件所属进程作用CarServiceHelperServiceSystemServer管理 Car Serivce 的系统服务CarServicebuiltin appCar 核心服务updatable appCar 核心服务的具体实现Car APIandroid.car.jarCar API SDKCar AppsLauncher 等Car 专门设计的一系列 App 而 CarService 在系统中的位置、与外部的交互链路则是通过一张总图来直观把握 SystemServer 进程在系统启动的时候发现 OS 具备 Automotive 的 feature则启动 CarServiceHelperService 系统服务并交由 CarServiceHelperServiceUpdatableImpl 实际负责和 CarService 的绑定CarService 的 builtin app 由父类 ServiceProxy 完成中转即反射出 updatable app 中 CarServiceImpl 实例CarServiceImpl 的初始化将构建 ICarImpl 实例并构建内部的一堆具体服务 CarServiceBase比如负责输入的 CarInputService、负责车辆属性的 CarPropertyService 等。这些具体服务通过 HalServiceBase 和 VehicleHal 进行交互比如调度输入事件的 InputHalService、读写/转换车辆属性的 PropertyHalService 等后续的交给 VehicleHal 通过 HIDL 和 HAL 层交互其他 Apps 可以通过 Car lib 提供的 Car API 获取 CarService 中的服务接口即 ICarImplICarImpl 通过启动时候注册的服务名称和 CarServiceBase 实例对照表向 Apps 返回对应的接口实例比如控制、监听输入的 CarInputManager、读写车辆属性的 CarPropertyManager其他 Apps 拿到这些 Manager 接口之后像 AOSP 中使用 ActivityManager 等接口一样通过 AIDL 和 CarService 进行交互 推荐阅读 一文了解 Android 车机如何处理中控的旋钮输入从实体按键看 Android 车载的自定义事件机制Android 车机初体验AutoAutomotive 傻傻分不清楚 参考文档 文章 https://developer.android.google.cn/reference/android/car/hardware/property/CarPropertyManagerhttps://developer.android.google.cn/reference/android/car/VehiclePropertyIds https://zhuanlan.zhihu.com/p/608622393https://www.jianshu.com/p/75da427d5682

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

建湖做网站哪家最好开通网站空间

在C和C中,int main(int argc, char* argv[])语句作为程序的入口,在main函数中常常用到。 argc:argument count,参数的数量。argc是一个整型数,代表传入程序的命令行参数的数量。程序名称是第一个参数,所以…

只做衬衣网站网站推广策划的策略

维护API很难。 我们正在维护非常复杂的jOOQ API。 但是就语义版本而言,我们遵循相对宽松的规则 。 当您阅读Brian Goetz和其他人关于在JDK中保持向后兼容性的评论时,我只能对他们的工作表示敬意。 显然,我们都希望最终移除Vector &#xff…

中国在数码网站注册域名好>软件工程师证书报考网站

C# 中的 Task< T> 是一个非常强大的并发编程工具&#xff0c;它允许我们异步执行操作并返回一个结果。在这篇博客中&#xff0c;我们将详细介绍 Task< T> 的应用&#xff0c;包括它的基本概念、创建方式、等待和取消等操作&#xff0c;以及一些常见的使用场景。 基…

专门做旅游攻略的网站抖音seo公司

npm - 软件包管理器 定义 npm是Node.js标准的软件包管理器 npm仓库中包含大量软件包,使其成为世界上最大的单一语言代码仓,并且可以确定几乎可用于一切的软件包 最初是为了下载和管理Node.js包依赖的方式,但其现在已成为前端JavaScript中使用的工具 使用: 1.初始化清单文…

wordpress在线仿站杭州 做网站

本篇介绍图像处理与模式识别中最热门的一个领域——人脸检测&#xff08;人脸识别&#xff09;。人脸检测可以说是学术界的宠儿&#xff0c;在不少EI&#xff0c;SCI高级别论文都能看到它的身影。甚至很多高校学生的毕业设计都会涉及到人脸检测。当然人脸检测的巨大实用价值也让…

对门户网站建设情况的报告省交通建设质安监督局网站

1.把client目录复制到服务器 .next和node_modules文件夹不用上传到服务器 在服务器目录运行 docker build -t fastgpt:1.0.3 . 构建服务 再运行 docker ps 就可以看到容器了

网站设计 加英文费用中国菲律宾争议岛屿

目录 1、首先创建一个maven项目引入spring依赖 2、新建一个person.java 实体类 3、新建配置类 TestBeanConfig.java 4、resources 创建配置文件 5、新建测试类TestBean.java 具体展示注解方式和配置方式的示例 今天给大家介绍一下Spring中Bean注解的用法,后续的文章给大家介绍S…

宝山手机网站制作公司网站内页全是404

文章目录1. 表格与树1.1 QTableView1.2 QListView1.3 QListWidget1.4 QTableWidget表根据界面宽度自动伸缩禁止编辑单击某单元&#xff0c;使之默认选中整行设置宽高度与内容相匹配是否显示表头单元格中放置控件输入行号&#xff0c;快速定位行设置颜色加粗字体排序文本对齐合并…

设计师如何做自己的个人网站帝国cms+wordpress

一、描述 运算符用于执行程序代码运算。 二、运算符主要包括&#xff1a; 算术运算符逻辑运算符关系运算符按位运算符赋值运算符三元/条件运算符字符串运算符类型运算符 1、算术运算符 y5&#xff0c;对下面算术运算符进行解释&#xff1a; 运算符 描述 例子 x 运算结果…

容桂网站开发创办网页

查看文件系统相关属性的命令&#xff1a;blkidblkid是一个查看磁盘设备属性相关信息的命令行工具blkid -L LABEL | UUID :根据UUID查看对应的设备是哪个blkid [-ghlv] [-c file] [-w file] [-o format][-s tag] [-t NAMEvalue] device [device ...]-i&#xff1a;显示io限制lsb…

莆田专业网站制作网站查询功能代码

文章目录 什么是m估计怎么求解m估计呢&#xff1f;Huber函数时的线性m估计 什么是m估计 自20世纪60年代稳健统计建立以来&#xff0c;在国内外众多学者的研究之下&#xff0c;诞生了一系列稳健统计重要理论和成果。其中最主要且广泛使用的稳健统计有以下三类&#xff1a; L-e…

四川高速公路建设集团网站更改wordpress主题语言

文章目录 前言MPU6050参数电路MPU6050框图 IIC外设框图 IIC的基本结构软件IIC实现MPU6050硬件IIC实现MPU6050 前言 在51单片机专栏中&#xff0c;用过I2C通信来进行实现AT24C02的数据存储&#xff1b; 里面介绍的是利用程序的编程来实现I2C的时序&#xff0c;进而实现AT24C02与…

网站企业建设公司排名空间设计大师

2018年第七届数学建模国际赛小美赛 C题 共享单车对城市交通的影响 原题再现&#xff1a; 共享自行车改变了许多城市的交通状况&#xff0c;许多大城市引入共享自行车来解决交通问题。我们需要定量评估共享自行车对城市交通的影响&#xff0c;以及相关的经济、社会和环境影响。…

深圳网站设计比较好的公司上海市住房和城乡建设厅

在所有关于C#事件机制的介绍中&#xff0c;我更倾向于发布者/订阅者&#xff08;Publisher/Subscriber&#xff09;这种描述。理解事件机制并不是一件容易的事情&#xff0c;它所涉及的思想值得我们好好去研究。 本文资源来自《C#与.NET技术平台实战演练》——中国青年出版社 …

网站建设流程分几步个人互动网站

http://blog.csdn.net/chenjinyu_tang/article/details/8136841 好久没有学习python了&#xff0c;应为工作的需要&#xff0c;再次拾起python&#xff0c;唤起记忆。 当函数的参数不确定时&#xff0c;可以使用*args 和**kwargs&#xff0c;*args 没有key值&#xff0c;**kwar…

长沙品牌网站建设实力强去哪个网站可以接单做ps等等

C# 9 新特性 —— 补充篇Intro前面我们分别介绍了一些 C# 9 中的新特性&#xff0c;还有一些我觉得需要了解一下的新特性&#xff0c;写一篇作为补充。Top-Level Statements在以往的代码里&#xff0c;一个应用程序必须要有 Main 方法才能运行&#xff0c;从 C# 9 开始&#xf…

如何建网站模板小型网站建设方案

我想创建一个具有95&#xff05;“精确”置信椭圆的二元正态分布的散点图.library(mvtnorm)library(ggplot2)set.seed(1)n c95 rho Sigma 我从双变量法线生成了1000个观测值,平均值为零,方差西格玛x z for(i in 1:n){z[i] p95[i] }我们可以使用stat_ellipse轻松地在生成数据的散…

门户网站建设的意义latex写wordpress

Java中线程的状态分为6种&#xff1a; 1.初始(NEW)&#xff1a;新创建了一个线程对象&#xff0c;但还没有调用start()方法。 2.运行(RUNNABLE)&#xff1a;Java线程中将就绪&#xff08;READY&#xff09;和运行中&#xff08;RUNNING&#xff09;两种状态笼统的称为“运行”…

网站建设拿什么框架海曙区做网站

解决数据库中的中文数据在页面显示乱码的问题 在连接的$connectionInfo中设置"CharacterSet" > "UTF-8"&#xff0c;指定编码方式即可 $connectionInfo array("UID">$uid, "PWD">$pwd, "Database">$database…