Android Framework增加新的系统服务详解
来源:互联网 发布:c语言 n 编辑:程序博客网 时间:2024/06/05 15:01
Android Framework系统服务详解
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
- package android.service.test;
- interface IMyTestManager {
- String sayHello();
- int priFunction();
- }
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 \
- …
## READ ME: ########################################################
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;
- }
- }
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; }}
路径: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();
- }
- }
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);
- }
- …
- }
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”;
- …
.../*** 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";...
路径: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);
- }
- });
- …
- }
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;
- }
- …
- }
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; } ...}
- MyTestManager mTestManager = (MyTestManager) getSystemService(Context.MYTEST_SERVICE);
- try {
- //这里调用不出priFunction(),MyTestManager没有对它进行再次封装
- mTestManager.sayHello();
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
MyTestManager mTestManager = (MyTestManager) getSystemService(Context.MYTEST_SERVICE);try { //这里调用不出priFunction(),MyTestManager没有对它进行再次封装 mTestManager.sayHello();} catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace();}
阅读全文
0 0
- Android Framework增加新的系统服务详解
- android framework增加新的系统服务
- Android Framework系统服务详解
- Android Framework系统服务详解
- Android系统的Application Frameworks层增加系统服务
- [android]Framework新增系统服务
- android framework添加系统服务
- android framework 添加系统服务
- Android 往Framework中添加新资源的方法详解
- Android 往Framework中添加新资源的方法详解
- android 在framework层增加服务后编译报错
- android系统服务详解
- Android自定义增加系统服务和AIDL
- android framework下新增系统服务Service
- Android framework层自定义系统服务
- android framework重要的服务
- Android 如何增加新的字库
- android 增加一个新的硬按键
- linux下Tomcat安装
- [bzoj1112][POI2008]砖块Klo
- Dubbo-Admin管理平台和Zookeeper注册中心的搭建
- mysql主从复制、基于gtid的主从复制、并行复制、半同步
- 把数组排成最小的数java实现
- Android Framework增加新的系统服务详解
- 自定义圆形刻度盘
- Kotlin 标准库扩展函数
- kmp
- 【安全牛学习笔记】KALI版本更新(第一个ROLLING RELEASE)和手动漏洞挖掘(SQL注入)
- Hello级别的Servlet
- Android NoClassDefFoundError崩溃问题
- crontab 保存并退出
- 1000: 整数a+b