您的位置:首页 > 移动开发 > Android开发

Android Framework系统服务详解

2016-09-13 09:53 369 查看
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

package android.service.test;  

  

interface IMyTestManager {  

    String sayHello();  

    int priFunction();  

}  

2.2 将创建的AIDL加入编译中

路径:frameworks/base/Android.mk

[javascript] view
plain copy

## 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

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

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

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

...  

/** 

* 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

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

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

MyTestManager mTestManager = (MyTestManager) getSystemService(Context.MYTEST_SERVICE);  

try {  

    //这里调用不出priFunction(),MyTestManager没有对它进行再次封装  

    mTestManager.sayHello();  

} catch (RemoteException e) {  

    // TODO Auto-generated catch block  

    e.printStackTrace();  

}

原文地址: http://blog.csdn.net/u012169524/article/details/51264979
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: