背景
众所周知,互联网行业发展的并不愉快,导致互联网行业就业形势不太理想,“开猿节流”的事情时有发生,所以很多小伙伴开启了车载android的学习,我也不例外。
AutoMovie和auto:
车载Android系统,又称Android Automotive, 是一个基于 Android 平台扩展后,适用于现代汽车的智能操作系统,可以直接运行为Android系统开发的应用。Android Automotive并非Android的分支或并行开发版本。它与手机和平板电脑等设备上搭载的Android使用相同的代码库,位于同一个存储区中。Android Automotive与Android最大的区别在于,Android Automotive增加了对汽车特定要求、功能和技术的支持。auto则是类似于carplay一样app
AutoMoive架构
这个就是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官方认证微信卡片免费领取↓↓↓