android service

getContext().getSystemService

        CarrierConfigManager configManager = (CarrierConfigManager)
                phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);

通过调用context的getSystemService函数可以获取系统的一些服务。那这些服务是在哪里初始化的呢?

Context的实现类为ContextImpl

class ContextImpl extends Context

getSystemService实际调用的是下面的两个函数

    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }

    @Override
    public String getSystemServiceName(Class<?> serviceClass) {
        return SystemServiceRegistry.getSystemServiceName(serviceClass);
    }

其实重要的东西都在SystemServiceRegistry类里

final class SystemServiceRegistry 
{
    private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
            new HashMap<Class<?>, String>();
    static {
        registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
                new CachedServiceFetcher<CarrierConfigManager>() {
            @Override
            public CarrierConfigManager createService(ContextImpl ctx) {
                return new CarrierConfigManager();
            }});

        registerService(Context.TELECOM_SERVICE, TelecomManager.class,
                new CachedServiceFetcher<TelecomManager>() {
            @Override
            public TelecomManager createService(ContextImpl ctx) {
                return new TelecomManager(ctx.getOuterContext());
            }});

        //此处省略了其他很多服务的注册...
    }

    private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }

    public static String getSystemServiceName(Class<?> serviceClass) {
        return SYSTEM_SERVICE_NAMES.get(serviceClass);
    }
   }

ServiceManager service

这种服务要区别于上面的服务

android系统提供了很多系统服务,ServiceManager 负责管理服务的添加以及获取。所以存在两方面的问题:

  1. 服务是怎么注册进系统的,因为只有注册进系统,才能被客户端请求获取到;
  2. 客户端如何获取服务以及如何和服务端通信。

为了便于理解,以ITelecomService为例

涉及到的文件包括

\frameworks\base\telecomm\java\com\android\internal\telecom\ITelecomService.aidl
\packages\services\Telecomm\src\com\android\server\telecom\TelecomServiceImpl.java
\frameworks\base\services\core\java\com\android\server\telecom\TelecomLoaderService.java
\frameworks\base\telephony\java\android\telephony\TelephonyManager.java
TelecomService.java

首先来看TelecomService

public class TelecomService extends Service implements TelecomSystem.Component {

这个类继承于SystemService ,客户端一般调用bindservice函数来连接和绑定这个服务,比如在TelecomLoaderService里

    private class TelecomServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // Normally, we would listen for death here, but since telecom runs in the same process
            // as this loader (process="system") thats redundant here.
            try {
                service.linkToDeath(new IBinder.DeathRecipient() {
                    @Override
                    public void binderDied() {
                        connectToTelecom();
                    }
                }, 0);
                SmsApplication.getDefaultMmsApplication(mContext, false);
                ServiceManager.addService(Context.TELECOM_SERVICE, service);
    ...此处省略了后续的代码
    }

    private void connectToTelecom() {
        synchronized (mLock) {
            if (mServiceConnection != null) {
                // TODO: Is unbinding worth doing or wait for system to rebind?
                mContext.unbindService(mServiceConnection);
                mServiceConnection = null;
            }

            TelecomServiceConnection serviceConnection = new TelecomServiceConnection();
            Intent intent = new Intent(SERVICE_ACTION);
            intent.setComponent(SERVICE_COMPONENT);
            int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
                    | Context.BIND_AUTO_CREATE;

            // Bind to Telecom and register the service
            if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.SYSTEM)) {
                mServiceConnection = serviceConnection;
            }
        }
    }

通过调用bindServiceAsUser 来绑定TelecomService服务,这个函数传入的两个参数serviceConnection和intent是关键:

serviceConnection:是当绑定成功后,这个对象的onServiceConnected函数会被调用,在这个函数里有一句

ServiceManager.addService(Context.TELECOM_SERVICE, service);

他的作用是将服务返回的一个ibinder句柄注册到系统服务里,之后在其他应用里就可以通过 ServiceManager.getService(Context.TELECOM_SERVICE 来获取这个ibinder对象,即获取服务,比如在TelephonyManager里

    private ITelecomService getTelecomService() {
        //得到TelecomServiceImpl的代理对象
        return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
    }

intent是用来寻找制定服务的

Intent intent = new Intent(SERVICE_ACTION);

在TelecomService 所在的父目录里有一个manifest文件,声明了这个服务

        <service android:name=".components.TelecomService"
                android:singleUser="true"
                android:process="system">
            <intent-filter>
                <action android:name="android.telecom.ITelecomService" />
            </intent-filter>
        </service>

所以当执行完bindServiceAsUser时,实际绑定的是TelecomService,其里面的onBind函数会返回一个IBinder对象,这个对象就是上面回调函数public void onServiceConnected(ComponentName name, IBinder service) 里的IBinder

    public IBinder onBind(Intent intent) {
        Log.d(this, "onBind");
        initializeTelecomSystem(this);
        synchronized (getTelecomSystem().getLock()) {
            return getTelecomSystem().getTelecomServiceImpl().getBinder();
        }
    }

getTelecomSystem().getTelecomServiceImpl().getBinder() 实际得到的是下面的mBinderImpl

public class TelecomServiceImpl {
  private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
}

参考:
https://blog.csdn.net/linyongan/article/details/52104394
https://www.cnblogs.com/sevenyuan/archive/2013/03/22/2975122.html 第四节
https://blog.csdn.net/jason_wzn/article/details/58164251
https://blog.csdn.net/sgzy001/article/details/54344739

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yiqingyang2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值