Android--ネットワーク関連のシステムサービス起動の簡単な分析
7042 ワード
Android--ネットワーク関連のシステムサービス起動の簡単な分析
Androidの多くのシステムサービスはSystemServerで開始されています.一般的には2つの方法があります. SystemServiceManager.startServcie() ServiceManageraddService()
前者も後者によってAndroidのサービスシステムに1つのサービスを追加した.AndroidのサービスシステムはBinderに基づいて実現されていることを知っています.Javaコードで呼び出されるこれらの起動・追加サービスの方法は,実際には下位層のC++が実現するサービス体系のコードパッケージであり,ここでは深く検討しない.
Ethernetサービスを例に、サービスの開始手順を簡単に説明します.SystemServerにアクセスするには:
onBootPhase()はbootの各フェーズで呼び出されます.EthernetサービスでシステムがPHASE_にある場合SYSTEM_SERVICES_READYフェーズの場合、Ethernet ServiceImplが呼び出されます.start()メソッドでは、Ethernetの初期化作業を行います.
これでEthernetサービスの起動プロセスは終了します.
Androidの多くのシステムサービスはSystemServerで開始されています.一般的には2つの方法があります.
前者も後者によってAndroidのサービスシステムに1つのサービスを追加した.AndroidのサービスシステムはBinderに基づいて実現されていることを知っています.Javaコードで呼び出されるこれらの起動・追加サービスの方法は,実際には下位層のC++が実現するサービス体系のコードパッケージであり,ここでは深く検討しない.
Ethernetサービスを例に、サービスの開始手順を簡単に説明します.SystemServerにアクセスするには:
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);
}
Ethernetがサポートされている場合はSystemServiceManagementが呼び出されます.startService()メソッドは、サービスを開始します. /**
* Starts a service by class name.
*
* @return The service instance.
*/
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
final Class serviceClass;
try {
serviceClass = (Class)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 startService(Class 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 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;
}
startService()反射により構造関数を呼び出してEthernetサービスのインスタンス化対象を得る.また,EthernetサービスではEthernet Managerのサービス側であるEthernetサービスインプラントオブジェクトが作成されます.EthernetサービスのonStart()メソッドを呼び出し、このサービスを登録します.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();
}
}
}
Ethernetサービスはシステムサービスから継承されます.SystemServiceは抽象クラスであり、システムプロセスで実行されるサービスを表すために設計されています.ライフサイクルフェーズによっては、ライフサイクルの異なるフェーズでいくつかの作業を完了するために、多くのシステムコールバック方法が提供されます.ここでは主に2つの方法を見ます. /**
* 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) {}
サービスを開始する必要がある場合、onStart()メソッドを呼び出してサービスをServiceManagerに登録します. /**
* 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の各フェーズで呼び出されます.EthernetサービスでシステムがPHASE_にある場合SYSTEM_SERVICES_READYフェーズの場合、Ethernet ServiceImplが呼び出されます.start()メソッドでは、Ethernetの初期化作業を行います.
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 Managerがインタフェースを外部に露出し,Ethernet ServiceImplがEthernet Managerにサービスを提供し,Ethernet NetworkFactoryがすべてのネットワーク管理操作を請け負う.これでEthernetサービスの起動プロセスは終了します.