Android Framework系统服务详解
16lz
2021-01-23
Android Framework系统服务详解
操作环境 系统:Linux (Ubuntu 12.04) 平台:高通
Android版本:5.1 PS: 符号...为省略N条代码
一、大致原理分析 Android本身有很多系统服务,如:AlarmManagerService、PowerManagerService、AudioService等,这些服务在手机系统启动时就进行开启或监听状态,由ServiceManager负责实例化运行。系统服务与本地新增的服务属于两个不同进程,必须通过AIDL(Android Interface Definition Language :Android接口定义语言)进行跨进程通信
二、新增具体案例
2.1 创建AIDL接口文件
路径:frameworks/base/core/java/android/service/test/IMyTestManager.aidl
2.2 将创建的AIDL加入编译中 路径:frameworks/base/Android.mk
当更新这个文件列表时,如果考虑aidl是SDK API的一部分。如果它是,同时添加到下面的列表进行预处理和分布式的SDK。这个列表不包含任何aidl文件parcelables接口。但是如果你想让第三方能够在整个过程发送这些对象的话,你就应该下面有一个的目标 2.2.2 LOCAL_SRC_FILES += \ 这个宏是编译管理AIDL的,很多系统AIDL在此添加进行编译 2.2.3 在frameworks/base/下用mm进行单编,把AIDL的java接口生成出来 编译完成后检查路径: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/service/test/IMyTestManager.java
2.3 创建新的系统服务类
路径:frameworks/base/core/java/android/service/test/MyTestManagerService.java
2.4 创建系统服务公开接口管理类
路径:frameworks/base/core/java/android/service/test/MyTestManager.java
2.5 将创建的服务添加进ServiceManager 路径:frameworks/base/services/java/com/android/server/SystemServer.java
2.6 注册服务
路径:frameworks/base/core/java/android/app/ContextImpl.java
2.7 调用新增的系统服务
操作环境 系统:Linux (Ubuntu 12.04) 平台:高通
Android版本:5.1 PS: 符号...为省略N条代码
一、大致原理分析 Android本身有很多系统服务,如:AlarmManagerService、PowerManagerService、AudioService等,这些服务在手机系统启动时就进行开启或监听状态,由ServiceManager负责实例化运行。系统服务与本地新增的服务属于两个不同进程,必须通过AIDL(Android Interface Definition Language :Android接口定义语言)进行跨进程通信
二、新增具体案例
2.1 创建AIDL接口文件
路径:frameworks/base/core/java/android/service/test/IMyTestManager.aidl
package android.service.test;interface IMyTestManager { String sayHello(); int priFunction();}
2.2 将创建的AIDL加入编译中 路径:frameworks/base/Android.mk
## READ ME: ############################################################ When updating this list of aidl files, consider if that aidl is## part of the SDK API. If it is, also add it to the list below that## is preprocessed and distributed with the SDK. This list should## not contain any aidl files for parcelables, but the one below should## if you intend for 3rd parties to be able to send those objects## across process boundaries.#### READ ME: ########################################################LOCAL_SRC_FILES += \...core/java/android/service/test/IMyTestManager.aidl \...
2.2.1 注释的大概意思:当更新这个文件列表时,如果考虑aidl是SDK API的一部分。如果它是,同时添加到下面的列表进行预处理和分布式的SDK。这个列表不包含任何aidl文件parcelables接口。但是如果你想让第三方能够在整个过程发送这些对象的话,你就应该下面有一个的目标 2.2.2 LOCAL_SRC_FILES += \ 这个宏是编译管理AIDL的,很多系统AIDL在此添加进行编译 2.2.3 在frameworks/base/下用mm进行单编,把AIDL的java接口生成出来 编译完成后检查路径: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/service/test/IMyTestManager.java
2.3 创建新的系统服务类
路径:frameworks/base/core/java/android/service/test/MyTestManagerService.java
public class MyTestManagerService extends IMyTestManager.Stub{ private static final String TAG = "MyTestManagerService"; private Context mContext; public MyTestManagerService(Context context) { mContext = context; } @Override public String sayHello() throws RemoteException { // TODO Auto-generated method stub Log.d(TAG, "sayHello()"); return "Hello AIDL"; } @Override public int priFunction() throws RemoteException { // TODO Auto-generated method stub Log.d(TAG, "priFunction()"); return 0; }}
2.4 创建系统服务公开接口管理类
路径:frameworks/base/core/java/android/service/test/MyTestManager.java
public class MyTestManager { private static final String TAG = "MyTestManager"; private IMyTestManager mService; public MyTestManager(IMyTestManager service) { mService = service; } public String sayHello() throws RemoteException { Log.d(TAG, "sayHello()"); return mService.sayHello(); }}
2.4.1 Android系统中很多系统服务API没有全部公开,都是在Frameworks层通过Manager类封装一层来进行管理公开接口。也就是说对Application层公开都是通过Manager封装来决定的,这里我只公开了sayHello()。priFunction()是我故意不公开的,方便理解2.5 将创建的服务添加进ServiceManager 路径:frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() { ... AudioService audioService = null; MyTestManagerService mTestService = null; ... if (!disableMedia && !"0".equals(SystemProperties.get("system_init.startaudioservice"))) { try { Slog.i(TAG, "Audio Service"); audioService = new AudioService(context); ServiceManager.addService(Context.AUDIO_SERVICE, audioService); } catch (Throwable e) { reportWtf("starting Audio Service", e); } } ... try { Slog.i(TAG, "MyTestManager Service"); mTestService = new MyTestManagerService(context); ServiceManager.addService(Context.MYTEST_SERVICE, mTestService); } catch (Throwable e) { reportWtf("starting MyTestManager", e); } ...}
2.5.1 为了阅读思路清晰,我保留了AudioService的服务添加代码。至于if条件,我们也可以添加,java里面控制的话可以在config.xml中定义bool类型,一般是为了区分多个项目的差异。涉及到项目的overlay,可根据操作项目的具体需求来进行。驱动底层一般都是宏控,稍微提一下。 2.5.2 代码中的Context.MYTEST_SERVICE服务常量添加 路径:frameworks/base/core/java/android/content/Context.java.../*** Use with {@link #getSystemService} to retrieve a* {@link android.media.AudioManager} for handling management of volume,* ringer modes and audio routing.** @see #getSystemService* @see android.media.AudioManager*/public static final String AUDIO_SERVICE = "audio";public static final String MYTEST_SERVICE = "mytest";...
2.6 注册服务
路径:frameworks/base/core/java/android/app/ContextImpl.java
static { ... registerService(AUDIO_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new AudioManager(ctx); } }); registerService(MYTEST_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder iBinder = ServiceManager.getService(Context.MYTEST_SERVICE); if (iBinder == null) { return null; } IMyTestManager service = IMyTestManager.Stub .asInterface(iBinder); return new MyTestManager(service); } }); ...}
2.6.1 在这里可以看到明显的对比,有一个差异就是AudioManager在注册服务的时候并没有像我添加的一样将服务传给IBinder,再通过IBinder来进行接口对接获取到服务。其实,AudioManger已经在内部类做了这层封装,原理是一样的,也有很多系统服务采用我这种方式进行注册。附AudioManager部分源码: 路径:frameworks/base/media/java/android/media/AudioManager.java public class AudioManager { ... private static IAudioService sService; /** * @hide */ public AudioManager(Context context) { mContext = context; ... } private static IAudioService getService() { if (sService != null) { return sService; } IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); sService = IAudioService.Stub.asInterface(b); return sService; } ...}
2.7 调用新增的系统服务
MyTestManager mTestManager = (MyTestManager) getSystemService(Context.MYTEST_SERVICE);try { //这里调用不出priFunction(),MyTestManager没有对它进行再次封装 mTestManager.sayHello();} catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace();}
更多相关文章
- Android Webview调用系统相册实现多选图片上传
- android 系统属性 build.prop
- 【译】Android 6.0接口变化(三)(Android 6.0 Changes)
- Android 系统音量最大值的定义位置以及默认值的修改方法
- android 系统关机,重启
- 在4.0以上系统中应用出现2.3版本的系统UI
- 【翻译】(8-补丁1)Android接口定义语言(AIDL)
- Android获取程序路径 (/data/data/appname)
- 修改系统分辨率