AIDL 调用过程详解
来源:互联网 发布:算法分析导论 编辑:程序博客网 时间:2024/05/21 16:58
目的:不同进程间的的IPC 通信
代码示例:
/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.car;import android.content.Intent;import android.car.ICarConnectionListener;/** @hide */interface ICar { IBinder getCarService(in String serviceName) = 0; int getCarConnectionType() = 1;}
声明了两个接口 getCarService 和getCarConnectionType
接口的实现在什么地方呢?
* Copyright (C) 2015 The Android Open Source Projectpackage com.android.car;import android.car.Car;public class ICarImpl extends ICar.Stub { public static final String INTERNAL_INPUT_SERVICE = "internal_input"; // load jni for all services here static { System.loadLibrary("jni_car_service"); } @GuardedBy("ICarImpl.class") private static ICarImpl sInstance = null; private final Context mContext; private final VehicleHal mHal; private final CarPowerManagementService mCarPowerManagementService; private final CarPackageManagerService mCarPackageManagerService; private final CarInputService mCarInputService; private final CarSensorService mCarSensorService; private final CarInfoService mCarInfoService; private final CarAudioService mCarAudioService; private final CarProjectionService mCarProjectionService; private final CarCameraService mCarCameraService; private final CarHvacService mCarHvacService; private final CarRadioService mCarRadioService; private final CarNightService mCarNightService; private final AppContextService mAppContextService; private final GarageModeService mGarageModeService; private final CarNavigationService mCarNavigationService; private final InstrumentClusterService mInstrumentClusterService; /** Test only service. Populate it only when necessary. */ @GuardedBy("this") private CarTestService mCarTestService; private final CarServiceBase[] mAllServices; public synchronized static ICarImpl getInstance(Context serviceContext) { if (sInstance == null) { sInstance = new ICarImpl(serviceContext); sInstance.init(); } return sInstance; } public synchronized static void releaseInstance() { if (sInstance == null) { return; } sInstance.release(); sInstance = null; } public ICarImpl(Context serviceContext) { mContext = serviceContext; mHal = VehicleHal.getInstance(); mCarPowerManagementService = new CarPowerManagementService(serviceContext); mCarInputService = new CarInputService(serviceContext); mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService); mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService); mCarInfoService = new CarInfoService(serviceContext); mAppContextService = new AppContextService(serviceContext); mCarSensorService = new CarSensorService(serviceContext); mCarAudioService = new CarAudioService(serviceContext); mCarHvacService = new CarHvacService(serviceContext); mCarRadioService = new CarRadioService(serviceContext); mCarCameraService = new CarCameraService(serviceContext); mCarNightService = new CarNightService(serviceContext); mCarPackageManagerService = new CarPackageManagerService(serviceContext); mInstrumentClusterService = new InstrumentClusterService(serviceContext); mCarNavigationService = new CarNavigationService( serviceContext, mAppContextService, mInstrumentClusterService); // Be careful with order. Service depending on other service should be inited later. mAllServices = new CarServiceBase[] { mCarPowerManagementService, mCarPackageManagerService, mCarInputService, mGarageModeService, mCarInfoService, mAppContextService, mCarSensorService, mCarAudioService, mCarHvacService, mCarRadioService, mCarCameraService, mCarNightService, mInstrumentClusterService, mCarProjectionService, mCarNavigationService, }; } private void init() { for (CarServiceBase service: mAllServices) { service.init(); } } private void release() { // release done in opposite order from init for (int i = mAllServices.length - 1; i >= 0; i--) { mAllServices[i].release(); } VehicleHal.releaseInstance(); } /** Only for CarTestService */ void startMocking() { reinitServices(); } /** Only for CarTestService */ void stopMocking() { reinitServices(); } /** Reset all services when starting / stopping vehicle hal mocking */ private void reinitServices() { for (int i = mAllServices.length - 1; i >= 0; i--) { mAllServices[i].release(); } for (CarServiceBase service: mAllServices) { service.init(); } } @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_CONTEXT_SERVICE: return mAppContextService; case Car.PACKAGE_SERVICE: return mCarPackageManagerService; case Car.CAMERA_SERVICE: assertCameraPermission(mContext); return mCarCameraService; case Car.HVAC_SERVICE: assertHvacPermission(mContext); return mCarHvacService; case Car.RADIO_SERVICE: assertRadioPermission(mContext); return mCarRadioService; case Car.CAR_NAVIGATION_SERVICE: assertNavigationManagerPermission(mContext); return mCarNavigationService; case Car.PROJECTION_SERVICE: assertProjectionPermission(mContext); return mCarProjectionService; case Car.TEST_SERVICE: { assertVehicleHalMockPermission(mContext); 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; } } @Override public int getCarConnectionType() { if (!isInMocking()) { return Car.CONNECTION_TYPE_EMBEDDED; } else { return Car.CONNECTION_TYPE_EMBEDDED_MOCKING; } } public CarServiceBase getCarInternalService(String serviceName) { switch (serviceName) { case INTERNAL_INPUT_SERVICE: return mCarInputService; default: Log.w(CarLog.TAG_SERVICE, "getCarInternalService for unknown service:" + serviceName); return null; } } /** * Whether mocking underlying HAL or not. * @return */ public synchronized boolean isInMocking() { if (mCarTestService == null) { return false; } return mCarTestService.isInMocking(); } public static void assertVehicleHalMockPermission(Context context) { if (context.checkCallingOrSelfPermission(Car.PERMISSION_MOCK_VEHICLE_HAL) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("requires CAR_MOCK_VEHICLE_HAL permission"); } } public static void assertCameraPermission(Context context) { if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_CAMERA) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( "requires " + Car.PERMISSION_CAR_CAMERA); } } public static void assertNavigationManagerPermission(Context context) { if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_NAVIGATION_MANAGER) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( "requires " + Car.PERMISSION_CAR_NAVIGATION_MANAGER); } } public static void assertHvacPermission(Context context) { if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_HVAC) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( "requires " + Car.PERMISSION_CAR_HVAC); } } private static void assertRadioPermission(Context context) { if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_RADIO) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( "requires permission " + Car.PERMISSION_CAR_RADIO); } } public static void assertProjectionPermission(Context context) { if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_PROJECTION) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException( "requires " + Car.PERMISSION_CAR_PROJECTION); } } void dump(PrintWriter writer) { writer.println("*Dump all services*"); for (CarServiceBase service: mAllServices) { service.dump(writer); } CarTestService testService = mCarTestService; if (testService != null) { testService.dump(writer); } }}
如何确认这个代码就是ICar 接口的实现呢?
ICarImpl extends ICar.Stub
ICarImpl 继承了服务器端ICar.Stub
现在需要如何使用这个接口呢?
mService = ICar.Stub.asInterface(service);
*在连接Service的时候,服务端的Stub(Binder)以参数的形式传过来了–IBinder service,然后我们通过asInterface()方法获取它的实例对象。
我们从android对aidl文件自动生成的java类中可以看到asInterface()这个接口的实现,大概的意思就是:
如果客户端和服务端在同一个进程下,那么asInterface()将返回Stub对象本身,否则返回Stub.Proxy对象。
也就是说asInterface()返回的对象有两种可能(实际上有三种,还有一种是null),Stub和Stub.Proxy。它们有什么区别呢?
如果在同一个进程下的话,那么asInterface()将返回服务端的Stub对象本身,因为此时根本不需要跨进称通信,那么直接调用Stub对象的接口就可以了,返回的实现就是服务端的Stub实现,也就是根本没有跨进程通信;
如果不是同一个进程,那么asInterface()返回是Stub.Proxy对象,该对象持有着远程的Binder引用,因为现在需要跨进程通信,所以如果调用Stub.Proxy的接口的话,那么它们都将是IPC调用,它会通过调用transact方法去与服务端通信。
以上就是两者的区别。*
- AIDL 调用过程详解
- Android AIDL远程调用详解
- FM AIDL JNI 调用过程回顾
- 函数调用过程详解
- 函数调用过程详解
- Servlet调用过程详解
- 系统调用过程详解
- AIDL详解
- AIDL详解
- AIDL详解
- AIDL详解
- Service跨进程调用服务三部曲之AIDL详解(一)
- Service跨进程调用服务三部曲之AIDL详解(二)
- Service跨进程调用服务三部曲之AIDL详解(三)
- AIDL 使用详解 (一) Android跨进程调用
- Android 源码编译AIDL 使用实例讲解及Android Studio AIDL的调用详解
- 什么是aidl?Android AIDL详解
- 什么是aidl?Android AIDL详解
- protoc-gen-lua 编译、安装、使用教程
- 生产环境出现乱码
- Normalized Frequency(x PI rad/sample)含义
- Android ActivityLifecycleCallbacks 分析
- linux paltform驱动中的to_platform_device
- AIDL 调用过程详解
- 端口分类调研
- 欢迎使用CSDN-markdown编辑器
- Ocx控件测试方式
- UEditor 圖片上傳圖標灰色,不能用問題
- mysql创建多列唯一健
- LeetCode: 371. Sum of Two Integers
- Spring整合Struts2 、使用Result 、使用拦截器 、ValueStack
- 我的大学之路