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
[java] view plain copy
print?
  1. package android.service.test;  
  2.   
  3. interface IMyTestManager {  
  4.     String sayHello();  
  5.     int priFunction();  
  6. }  
package android.service.test;interface IMyTestManager {    String sayHello();    int priFunction();}

2.2 将创建的AIDL加入编译中

路径:frameworks/base/Android.mk

[javascript] view plain copy
print?
  1. ## READ ME: ########################################################  
  2. ##  
  3. ## When updating this list of aidl files, consider if that aidl is  
  4. ## part of the SDK API.  If it is, also add it to the list below that  
  5. ## is preprocessed and distributed with the SDK.  This list should  
  6. ## not contain any aidl files for parcelables, but the one below should  
  7. ## if you intend for 3rd parties to be able to send those objects  
  8. ## across process boundaries.  
  9. ##  
  10. ## READ ME: ########################################################  
  11. LOCAL_SRC_FILES += \  
  12. …  
  13. core/java/android/service/test/IMyTestManager.aidl \  
  14. …  
## 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
[java] view plain copy
print?
  1. public class MyTestManagerService extends IMyTestManager.Stub{  
  2.   
  3.     private static final String TAG = “MyTestManagerService”;  
  4.   
  5.     private Context mContext;  
  6.   
  7.     public MyTestManagerService(Context context) {  
  8.         mContext = context;  
  9.     }  
  10.   
  11.     @Override  
  12.     public String sayHello() throws RemoteException {  
  13.         // TODO Auto-generated method stub  
  14.         Log.d(TAG, ”sayHello()”);  
  15.         return “Hello AIDL”;  
  16.     }  
  17.       
  18.     @Override  
  19.     public int priFunction() throws RemoteException {  
  20.         // TODO Auto-generated method stub  
  21.         Log.d(TAG, ”priFunction()”);  
  22.         return 0;  
  23.     }  
  24.   
  25. }  
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
[java] view plain copy
print?
  1. public class MyTestManager {  
  2.   
  3.     private static final String TAG = “MyTestManager”;  
  4.   
  5.     private IMyTestManager mService;  
  6.   
  7.     public MyTestManager(IMyTestManager service) {  
  8.         mService = service;  
  9.     }  
  10.   
  11.     public String sayHello() throws RemoteException {  
  12.         Log.d(TAG, ”sayHello()”);  
  13.         return mService.sayHello();  
  14.     }  
  15. }  
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
[java] view plain copy
print?
  1. private void startOtherServices() {  
  2.     …  
  3.     AudioService audioService = null;  
  4.     MyTestManagerService mTestService = null;  
  5.     …  
  6.     if (!disableMedia && !“0”.equals(SystemProperties.get(“system_init.startaudioservice”))) {  
  7.         try {  
  8.             Slog.i(TAG, ”Audio Service”);  
  9.             audioService = new AudioService(context);  
  10.             ServiceManager.addService(Context.AUDIO_SERVICE, audioService);  
  11.         } catch (Throwable e) {  
  12.             reportWtf(”starting Audio Service”, e);  
  13.         }  
  14.     }  
  15.     …  
  16.     try {  
  17.         Slog.i(TAG, ”MyTestManager Service”);  
  18.         mTestService = new MyTestManagerService(context);  
  19.         ServiceManager.addService(Context.MYTEST_SERVICE, mTestService);  
  20.     } catch (Throwable e) {  
  21.         reportWtf(”starting MyTestManager”, e);  
  22.     }  
  23.     …  
  24. }  
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
[java] view plain copy
print?
  1. …  
  2. /** 
  3. * Use with {@link #getSystemService} to retrieve a 
  4. * {@link android.media.AudioManager} for handling management of volume, 
  5. * ringer modes and audio routing. 
  6. * 
  7. * @see #getSystemService 
  8. * @see android.media.AudioManager 
  9. */  
  10. public static final String AUDIO_SERVICE = “audio”;  
  11.   
  12. public static final String MYTEST_SERVICE = “mytest”;  
  13. …  
.../*** 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
[java] view plain copy
print?
  1. static {  
  2.     …  
  3.     registerService(AUDIO_SERVICE, new ServiceFetcher() {  
  4.         public Object createService(ContextImpl ctx) {  
  5.             return new AudioManager(ctx);  
  6.         }  
  7.     });  
  8.       
  9.     registerService(MYTEST_SERVICE, new ServiceFetcher() {  
  10.         public Object createService(ContextImpl ctx) {  
  11.             IBinder iBinder = ServiceManager.getService(Context.MYTEST_SERVICE);  
  12.                 if (iBinder == null) {  
  13.                     return null;  
  14.                 }  
  15.                 IMyTestManager service = IMyTestManager.Stub  
  16.                     .asInterface(iBinder);  
  17.                 return new MyTestManager(service);  
  18.             }  
  19.     });  
  20.     …  
  21. }  
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
[java] view plain copy
print?
  1. public class AudioManager {  
  2.     …  
  3.     private static IAudioService sService;  
  4.   
  5.     /** 
  6.      * @hide 
  7.      */  
  8.     public AudioManager(Context context) {  
  9.         mContext = context;  
  10.         …  
  11.     }  
  12.   
  13.     private static IAudioService getService()  
  14.     {  
  15.         if (sService != null) {  
  16.             return sService;  
  17.         }  
  18.         IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);  
  19.         sService = IAudioService.Stub.asInterface(b);  
  20.         return sService;  
  21.     }  
  22.     …  
  23. }  
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 调用新增的系统服务
[java] view plain copy
print?
  1. MyTestManager mTestManager = (MyTestManager) getSystemService(Context.MYTEST_SERVICE);  
  2. try {  
  3.     //这里调用不出priFunction(),MyTestManager没有对它进行再次封装  
  4.     mTestManager.sayHello();  
  5. catch (RemoteException e) {  
  6.     // TODO Auto-generated catch block  
  7.     e.printStackTrace();  
  8. }  
MyTestManager mTestManager = (MyTestManager) getSystemService(Context.MYTEST_SERVICE);try {    //这里调用不出priFunction(),MyTestManager没有对它进行再次封装    mTestManager.sayHello();} catch (RemoteException e) {    // TODO Auto-generated catch block    e.printStackTrace();}





原创粉丝点击