赞
踩
众所周知,互联网行业发展的并不愉快,导致互联网行业就业形势不太理想,“开猿节流”的事情时有发生,所以很多小伙伴开启了车载android的学习,我也不例外。
车载Android系统,又称Android Automotive, 是一个基于 Android 平台扩展后,适用于现代汽车的智能操作系统,可以直接运行为Android系统开发的应用。Android Automotive并非Android的分支或并行开发版本。它与手机和平板电脑等设备上搭载的Android使用相同的代码库,位于同一个存储区中。Android Automotive与Android最大的区别在于,Android Automotive增加了对汽车特定要求、功能和技术的支持。auto则是类似于carplay一样app
这个就是AndroidAutoMovie的架构图,总体来说关于android的部分在Framework中添加了大量的车机服务,并且在sdk中提供了api供我们调用,而在底层则添加了嵌入式操作系统相关的架构。关于底层我们只是做一些简单的了解,我们先来看看应用层和Framework层,先来看看这个车机服务是咋起来的那车机服务是咋起的呢?答案还是
在Systemserver里,
private void startOtherServices() {
... if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
traceBeginAndSlog("StartCarServiceHelperService");
mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
traceEnd();
}
... }
Systemserver通过SystemServiceManager来管理的,所以CAR_SERVICE_HELPER_SERVICE_CLASS同样也被它管理,我们来跟下代码
public SystemService startService(String className) { final Class<SystemService> serviceClass; try { serviceClass = (Class<SystemService>)Class.forName(className); } catch (ClassNotFoundException ex) { Slog.i(TAG, "Starting " + className); throw new RuntimeException("Failed to create service " + className + ": service class not found, usually indicates that the caller should " + "have called PackageManager.hasSystemFeature() to check whether the " + "feature is available on this device before trying to start the " + "services that implement it", ex); } return startService(serviceClass); } /** * Creates and starts a system service. The class must be a subclass of * {@link com.android.server.SystemService}. * * @param serviceClass A Java class that implements the SystemService interface. * @return The service instance, never null. * @throws RuntimeException if the service fails to start. */ @SuppressWarnings("unchecked") public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); Slog.i(TAG, "Starting " + name); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name); // Create the service. if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext);//反射获取对象 } catch (InstantiationException ex) { throw new RuntimeException("Failed to create service " + name + ": service could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (NoSuchMethodException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (InvocationTargetException ex) { throw new RuntimeException("Failed to create service " + name + ": service constructor threw an exception", ex); } startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { service.onStart();//最终调到了这个方法 } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart"); }
我们通过上面的代码可以看到,它最终是调了 CarServiceHelperService.onStart()这个方法,我们继续跟代码
@Override
public void onStart() {
Intent intent = new Intent();
intent.setPackage("com.android.car");
intent.setAction(CAR_SERVICE_INTERFACE);
if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
UserHandle.SYSTEM)) {
Slog.wtf(TAG, "cannot start car service");
}
System.loadLibrary("car-framework-service-jni");
}
这个方法里,启动一个包名为com.android.car并绑定得到一个binder远端代理,这样就完成了carService的启动,我们不难发现它就是个单独的app,写到这,我突然不免意思到,这个跟前公司智能android机顶盒的流程,简直如出一辙啊,cable线的直播电视app开发中,由中间件适配硬件,提供hal层给Framework调用,我们也是整了一个服务类的apk,这个通过抽象接口调用底层,并且提供binder给应用层绑定,那应用层咋绑定呢,也是通过一个jar包来做和服务类apk通讯,app只需要调用jar包中的api就够了,好了好像跑偏了,言归正传,我们继续说这个单独app,这个源码在哪里呢?/packages/services/Car/service,我们跟进去看一下它的代码
public class CarService extends Service { private static final long WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS = 10_000; private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); private static final String IVHAL_20 = android.hardware.automotive.vehicle.V2_0.IVehicle.kInterfaceName; private static final String IVHAL_21 = android.hardware.automotive.vehicle.V2_1.IVehicle.kInterfaceName; private CanBusErrorNotifier mCanBusErrorNotifier; private ICarImpl mICarImpl; //提供服务的远端stub private IVehicle mVehicle; //就理解为跟硬件打交道的抽象接口吧 private final VehicleDeathRecipient mVehicleDeathRecipient = new VehicleDeathRecipient(); @Override public void onCreate() { Log.i(CarLog.TAG_SERVICE, "Service onCreate"); mCanBusErrorNotifier = new CanBusErrorNotifier(this /* context */); mVehicle = getVehicle(null /* Any Vehicle HAL interface name */); if (mVehicle == null) { throw new IllegalStateException("Vehicle HAL service is not available."); } try { mVehicleInterfaceName = mVehicle.interfaceDescriptor(); } catch (RemoteException e) { throw new IllegalStateException("Unable to get Vehicle HAL interface descriptor", e); } Log.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName); mICarImpl = new ICarImpl(this, mVehicle, SystemInterface.getDefault(this), mCanBusErrorNotifier); mICarImpl.init(); SystemProperties.set("boot.car_service_created", "1"); linkToDeath(mVehicle, mVehicleDeathRecipient); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // keep it alive. return START_STICKY; } @Override public IBinder onBind(Intent intent) { return mICarImpl; } }
通过代码,我们不难发现mICarImpl应该是实现了stub的远端服务,我们跟下它的代码
public class ICarImpl extends ICar.Stub { private final CarServiceBase[] mAllServices; /** Test only service. Populate it only when necessary. */ @GuardedBy("this") private CarTestService mCarTestService; public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface, CanBusErrorNotifier errorNotifier) { mContext = serviceContext; mHal = new VehicleHal(vehicle); mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext); mCarPowerManagementService = new CarPowerManagementService( mHal.getPowerHal(), systemInterface); mCarSensorService = new CarSensorService(serviceContext, mHal.getSensorHal()); mCarPackageManagerService = new CarPackageManagerService(serviceContext, mCarSensorService, mSystemActivityMonitoringService); mCarInputService = new CarInputService(serviceContext, mHal.getInputHal()); mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService); mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService); mCarInfoService = new CarInfoService(serviceContext, mHal.getInfoHal()); mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService); mCarAudioService = new CarAudioService(serviceContext, mHal.getAudioHal(), mCarInputService, errorNotifier); mCarCabinService = new CarCabinService(serviceContext, mHal.getCabinHal()); mCarHvacService = new CarHvacService(serviceContext, mHal.getHvacHal()); mCarRadioService = new CarRadioService(serviceContext, mHal.getRadioHal()); mCarNightService = new CarNightService(serviceContext, mCarSensorService); mInstrumentClusterService = new InstrumentClusterService(serviceContext, mAppFocusService, mCarInputService); mSystemStateControllerService = new SystemStateControllerService(serviceContext, mCarPowerManagementService, mCarAudioService, this); mCarVendorExtensionService = new CarVendorExtensionService(serviceContext, mHal.getVendorExtensionHal()); mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext); mCarBluetoothService = new CarBluetoothService(serviceContext, mCarCabinService, mCarSensorService, mPerUserCarServiceHelper); if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal()); mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal()); } if (FeatureConfiguration.ENABLE_DIAGNOSTIC) { mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal()); } // Be careful with order. Service depending on other service should be inited later. List<CarServiceBase> allServices = new ArrayList<>(Arrays.asList( mSystemActivityMonitoringService, mCarPowerManagementService, mCarSensorService, mCarPackageManagerService, mCarInputService, mGarageModeService, mCarInfoService, mAppFocusService, mCarAudioService, mCarCabinService, mCarHvacService, mCarRadioService, mCarNightService, mInstrumentClusterService, mCarProjectionService, mSystemStateControllerService, mCarVendorExtensionService, mCarBluetoothService, mPerUserCarServiceHelper )); if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { allServices.add(mVmsSubscriberService); allServices.add(mVmsPublisherService); } if (FeatureConfiguration.ENABLE_DIAGNOSTIC) { allServices.add(mCarDiagnosticService); } mAllServices = allServices.toArray(new CarServiceBase[0]); } public void init() { mHal.init(); for (CarServiceBase service : mAllServices) { service.init(); } } public void release() { // release done in opposite order from init for (int i = mAllServices.length - 1; i >= 0; i--) { mAllServices[i].release(); } mHal.release(); } public void vehicleHalReconnected(IVehicle vehicle) { mHal.vehicleHalReconnected(vehicle); for (CarServiceBase service : mAllServices) { service.vehicleHalReconnected(); } } //提供对外服务获取api @Override public IBinder getCarService(String serviceName) { switch (serviceName) { case Car.AUDIO_SERVICE: return mCarAudioService; case Car.SENSOR_SERVICE: return mCarSensorService; case Car.INFO_SERVICE: return mCarInfoService; case Car.APP_FOCUS_SERVICE: return mAppFocusService; case Car.PACKAGE_SERVICE: return mCarPackageManagerService; case Car.CABIN_SERVICE: assertCabinPermission(mContext); return mCarCabinService; case Car.DIAGNOSTIC_SERVICE: FeatureUtil.assertFeature(FeatureConfiguration.ENABLE_DIAGNOSTIC); if (FeatureConfiguration.ENABLE_DIAGNOSTIC) { assertAnyDiagnosticPermission(mContext); return mCarDiagnosticService; } case Car.HVAC_SERVICE: assertHvacPermission(mContext); return mCarHvacService; case Car.RADIO_SERVICE: assertRadioPermission(mContext); return mCarRadioService; case Car.CAR_NAVIGATION_SERVICE: assertNavigationManagerPermission(mContext); IInstrumentClusterNavigation navService = mInstrumentClusterService.getNavigationService(); return navService == null ? null : navService.asBinder(); case Car.PROJECTION_SERVICE: assertProjectionPermission(mContext); return mCarProjectionService; case Car.VENDOR_EXTENSION_SERVICE: assertVendorExtensionPermission(mContext); return mCarVendorExtensionService; case Car.VMS_SUBSCRIBER_SERVICE: FeatureUtil.assertFeature(FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE); if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { assertVmsSubscriberPermission(mContext); return mVmsSubscriberService; } case Car.TEST_SERVICE: { assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE); synchronized (this) { if (mCarTestService == null) { mCarTestService = new CarTestService(mContext, this); } return mCarTestService; } } default: Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName); return null; } } }
这么多service看的眼睛都花了,不过确实是在这里面管理添加并缓存的,并且Car还把硬件抽象相关的vehicle传过来了,那各种服务拿到这个硬件接口,不就是可以操作硬件了嘛。以上就是carservice的启动过程。用一张图来表述各个功能模块
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。