Android -- 网络相关的系统服务启动简要分析
转自http://blog.youkuaiyun.com/csdn_of_coder/article/details/51636855
Android中众多的系统服务都是在SystemServer中启动的,一般有两种方式:
- SystemServiceManager.startServcie()
- ServiceManageraddService()
前一种方式也是通过后者将一个服务添加到Android的服务体系中的。我们知道,Android的服务体系都是基于Binder来实现的;Java代码里调用的这些启动、添加服务的方法,实际上是对底层C++实现的服务体系的代码封装,这里我们不做深入探讨。
我们以EthernetService为例,简单介绍下该服务的启动过程。进入SystemServer:
如果支持Ethernet,则会调用SystemServiceManager.startService()方法开启服务:
startService()通过反射,调用构造函数得到一个EthernetService的实例化对象;同时,EthernetService中会创建一个EthernetServiceImpl对象,它是EthernetManager的服务端。调用EthernetService的onStart()方法,注册该服务:
EthernetService继承自SystemService。SystemService是一个抽象类,它的设计初衷是用来表示一个运行在system进程中的服务。根据生命周期阶段的不同,它提供了很多系统回调方法,我们可以对它们进行重写,以在生命周期的不同阶段完成某些工作。这里主要看两个方法:
当我们需要启动一个服务时,调用onStart()方法将该服务注册到ServiceManager中;
- private static final String ETHERNET_SERVICE_CLASS =
- "com.android.server.ethernet.EthernetService";
- if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
- mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
- mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
- }
- /**
- * Starts a service by class name.
- *
- * @return The service instance.
- */
- @SuppressWarnings("unchecked")
- public SystemService startService(String className) {
- final Class<SystemService> serviceClass;
- try {
- serviceClass = (Class<SystemService>)Class.forName(className);
- } catch (ClassNotFoundException ex) {
- Slog.i(TAG, "Starting " + className);
- throw new RuntimeException("Failed to create service " + className
- + ": service class not found, usually indicates that the caller should "
- + "have called PackageManager.hasSystemFeature() to check whether the "
- + "feature is available on this device before trying to start the "
- + "services that implement it", ex);
- }
- return startService(serviceClass);
- }
- /**
- * Creates and starts a system service. The class must be a subclass of
- * {@link com.android.server.SystemService}.
- *
- * @param serviceClass A Java class that implements the SystemService interface.
- * @return The service instance, never null.
- * @throws RuntimeException if the service fails to start.
- */
- @SuppressWarnings("unchecked")
- public <T extends SystemService> T startService(Class<T> serviceClass) {
- final String name = serviceClass.getName();
- Slog.i(TAG, "Starting " + name);
- // Create the service.
- if (!SystemService.class.isAssignableFrom(serviceClass)) {
- throw new RuntimeException("Failed to create " + name
- + ": service must extend " + SystemService.class.getName());
- }
- final T service;
- try {
- Constructor<T> constructor = serviceClass.getConstructor(Context.class);
- service = constructor.newInstance(mContext);
- } catch (InstantiationException ex) {
- throw new RuntimeException("Failed to create service " + name
- + ": service could not be instantiated", ex);
- } catch (IllegalAccessException ex) {
- throw new RuntimeException("Failed to create service " + name
- + ": service must have a public constructor with a Context argument", ex);
- } catch (NoSuchMethodException ex) {
- throw new RuntimeException("Failed to create service " + name
- + ": service must have a public constructor with a Context argument", ex);
- } catch (InvocationTargetException ex) {
- throw new RuntimeException("Failed to create service " + name
- + ": service constructor threw an exception", ex);
- }
- // Register it.
- mServices.add(service);
- // Start it.
- try {
- service.onStart();
- } catch (RuntimeException ex) {
- throw new RuntimeException("Failed to start service " + name
- + ": onStart threw an exception", ex);
- }
- return service;
- }
- public final class EthernetService extends SystemService {
- private static final String TAG = "EthernetService";
- final EthernetServiceImpl mImpl;
- public EthernetService(Context context) {
- super(context);
- mImpl = new EthernetServiceImpl(context);
- }
- @Override
- public void onStart() {
- Log.i(TAG, "Registering service " + Context.ETHERNET_SERVICE);
- publishBinderService(Context.ETHERNET_SERVICE, mImpl);
- }
- @Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- mImpl.start();
- }
- }
- }
- /**
- * Called when the dependencies listed in the @Service class-annotation are available
- * and after the chosen start phase.
- * When this method returns, the service should be published.
- */
- public abstract void onStart();
- /**
- * Called on each phase of the boot process. Phases before the service's start phase
- * (as defined in the @Service annotation) are never received.
- *
- * @param phase The current boot phase.
- */
- public void onBootPhase(int phase) {}
- /**
- * Publish the service so it is accessible to other services and apps.
- */
- protected final void publishBinderService(String name, IBinder service) {
- publishBinderService(name, service, false);
- }
- /**
- * Publish the service so it is accessible to other services and apps.
- */
- protected final void publishBinderService(String name, IBinder service,
- boolean allowIsolated) {
- ServiceManager.addService(name, service, allowIsolated);
- }
onBootPhase()可以在boot的各个阶段被调用。在EthernetService中,当系统处于PHASE_SYSTEM_SERVICES_READY阶段时,会调用EthernetServiceImpl.start()方法,做一些Ethernet的初始化工作:
EthernetManager对外暴露接口,EthernetServiceImpl向EthernetManager提供服务,EthernetNetworkFactory包揽所有的网络管理操作。
- public void start() {
- Log.i(TAG, "Starting Ethernet service");
- HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
- handlerThread.start();
- mHandler = new Handler(handlerThread.getLooper());
- mTracker.start(mContext, mHandler);//EthernetNetworkFactory
- mStarted.set(true);
- }
这样,Ethernet服务的启动过程就结束了。