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 负责管理服务的添加以及获取。所以存在两方面的问题:
- 服务是怎么注册进系统的,因为只有注册进系统,才能被客户端请求获取到;
- 客户端如何获取服务以及如何和服务端通信。
为了便于理解,以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