标签:
Android设备的开机流程总得来分可以分为三部分:
引导程序bootloader是开机运行的第一个小程序,因此它是针对特定的主板与芯片的。bootloader有很多种,可以使用比较流行的如redboot、uboot、ARMBoot等,也可以开发自己的引导程序,它不是Android操作系统的一部分。引导程序也是OEM厂商或者运营商加锁和限制的地方。
引导程序初始化硬件设备、创建存储器空间的映射等软件运行时所需要的最小环境;加载Linux内核镜像文件(本文只针对Android、Linux)到RAM中某个地址处执行,此时引导程序的控制权就交给了内核。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。
说明:加电后,CPU将先执行bootloader程序,此处有三种选择:
a) 启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写
b) 启动到recovery模式,加载recovery.img,recovery.img包含内核,基本的文件系统,用于工程模式的烧写
c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况)
推荐阅读:[Android系统启动流程 – bootloader]
内核启动时,设置缓存、被保护存储器、计划列表,加载驱动等系统内部初始化工作。然后内核会寻找并执行”init”文件,创建init进程作为系统的第一个进程。推荐阅读:[Android系统启动流程 – linux kernel]
init进程是Linux内核启动之后启动的第一个用户级进程,Android的启动也是在这个进程的基础上开始的,进程号为1。如果是正常启动init会读取并解析init.rc文件,对于init.rc文件,Android中有特定的格式以及规则。在Android中,叫做Android初始化语言。读取解析文件的时,是以行为最小可执行单位解析。解析之后并不会马上执行,而是在init进入服务循环之前统一根据其命令本身所带的条件来执行。
推荐阅读:[Android的init过程详解 ]
init进程会读取init.rc中的service并按照顺序启动它们,它们是Android的守护进程,比如:
log守护进程(log Daemon):
service logd /system/bin/logd
class core
socket logd stream 0666 logd logd
socket logdr seqpacket 0666 logd logd
socket logdw dgram 0222 logd logd
seclabel u:r:logd:s0
adb守护进程:
service adbd /sbin/adbd --root_seclabel=u:r:su:s0
class core
socket adbd stream 660 system system
disabled
seclabel u:r:adbd:s0
servicemanager:
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
Network守护进程:
service netd /system/bin/netd
class main
socket netd stream 0660 root system
socket dnsproxyd stream 0660 root inet
socket mdns stream 0660 root system
socket fwmarkd stream 0660 root inet
surfaceflinger:
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
media:
service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm qcom_diag
ioprio rt 4
开机动画:
service bootanim /system/bin/bootanimation
class main
user root
group graphics audio
disabled
oneshot
关机动画:
service shutdownanim /system/bin/shutdownanimation
class main
user root
group graphics audio
disabled
oneshot
安装程序:
service installd /system/bin/installd
class main
socket installd stream 600 system system
flash恢复:
service flash_recovery /system/bin/install-recovery.sh
class main
seclabel u:r:install_recovery:s0
oneshot
守护进程是最底层的服务,他们的通信方式是socket。ServiceManager用来管理系统中所有的binder service,不管是本地的c++实现的还是java语言实现的都需要这个进程来统一管理,最主要的管理就是,注册添加服务,获取服务。所有的Service使用前都必须先在servicemanager中进行注册。
当启动servicemanager时,会启动 zygote,surfaceflinger等。Zygote这个进程是非常重要的一个进程,注册Zygote Socket服务端套接字;加载虚拟机;预加载Android核心类;预加载系统资源:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
onrestart setprop sys.android.reboot 1
zygote中会启动Xzygote和system-server,从SystemServer开始就是启动系统服务了:
启动SystemServer:
namespace android {
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// 启动传感器服务
SensorService::instantiate();
}
}
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService },
};
int register_android_server_SystemServer(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
gMethods, NELEM(gMethods));
}
}; // namespace android
com/android/server/SystemServer:
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices");//跟踪器开始跟踪
// 如果设备的时钟是 1970以前 (在 0以前), 很多API会发生异常,
// 特别是java.io.File#setLastModified,
// 所以我们假冒一个并且希望会很快获取时间.
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
// 如果系统有 "persist.sys.language" 和好友设置, 用"persist.sys.locale"代替它。
// 使用"-Duser.locale"命令记住默认的本地适当的时候 .
// 这个命令在AndroidRuntime 也用在设置系统属性,
// 但只有系统服务器和系统apps 呗允许设置他们.
//
// 注意: Most changes made here will need an equivalent change to
// core/jni/AndroidRuntime.cpp
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
// In case the runtime switched since last boot (such as when
// the old runtime was removed in an OTA), set the system
// property so that it is in sync. We can‘t do this in
// libnativehelper‘s JniInvocation::Init code where we already
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// 启用采样分析器.
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!好多内存
VMRuntime.getRuntime().clearGrowthLimit();
// 系统服务会一直运行,所以需要他的内存也一直有效.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//一些设备依赖 runtime 指纹生成, 所以在启动前确保我们已经声明了它.
Build.ensureFingerprintProperty();
//在系统服务器中,没有明确指定用户的访问环境路径是一个错误.
Environment.setUserRequired(true);
// 确保传进系统的binder总是以前台优先权运行.
BinderInternal.disableBackgroundScheduling(true);
// 准备 main looper thread (这个 thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// //加载android_servers.so库.
System.loadLibrary("android_servers");
// 检查上一次关机是否失败.
// 可以没有返回值.
performPendingShutdown();
// 初始化系统context.
createSystemContext();
// 创建 system service manager对象,添加到本地服务中
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);跟踪器结束跟踪
}
// 启动 services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");//跟踪器开始跟踪
startBootstrapServices();//启动引导服务
startCoreServices();//启动核心服务
startOtherServices();//启动其他服务
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
// 一直Loop .
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
从上面可以看出,先是初始化系统context,然后启动SystemServiceManager,再然后就是启动BootstrapServices,CoreServices,OtherServices。BootstrapServices是让系统启动的并且会相互影响的关键服务,第一个就是ActivityManagerService:
/**启动引导服务
* 启动相互影响的关键服务 that 让系统开始启动
* 这些服务有复杂的相互依赖关系,这就是为什么我们把它们都放在这一个地方
* 除非你的服务也和这些依赖关系有缠绕,它应该是在另一个功能里的进行初始化.
*/
private void startBootstrapServices() {
// 等待installd to 完成启动 ,所以它有一次机会去创建关键目录,和相关权限。比如/data/user
// 我们需要这个来完成之前我们初始化的其他服务。
Installer installer = mSystemServiceManager.startService(Installer.class);//安装程序,程序安装器
// 这个由Activity manager 运行.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);//设置系统服务管理器
mActivityManagerService.setInstaller(installer);//设置安装程序
// Power manager需要很早启动,因为其他服务需要他.
// 本地守护进程可以监听到他被注册,所以他必须时刻准备着处理传进的binder。
// (包括能够验证这些调用的权限).
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// 现在这个power manager 已经启动了,让activity manager初始化power management功能.
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
mActivityManagerService.initPowerManagement();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// 管理LEDs 和 display backlight 所以我们需要他 to bring up the display.
mSystemServiceManager.startService(LightsService.class);
// Display manager需要用来提供显示度量值 在package manager启动前。
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//我们需要默认的display,在我们可以初始化package manager之前.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
//如果我们加密了设备,只运行"core" apps. decrypt:加密
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// 启动package manager.
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);//启动PackageManagerService
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();//获取PackageManager
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
//用户服务添加到服务管理器中
traceBeginAndSlog("StartUserManagerService");
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// 初始化用于缓存包中资源的缓存属性.
AttributeCache.init(mSystemContext);
// 为系统进程构建应用实例并且启动.
mActivityManagerService.setSystemProcess();
//传感器服务需要访问包管理器服务、应用程序ops服务和权限服务,因此,我们在他们之后启动它。
startSensorService();
}
接着启动一些必要的相对独立的系统服务:
/**
* 启动一些必要的,没和bootstrap 过程中的纠缠 ,的服务.
*/
private void startCoreServices() {
// 跟踪电池电量. 要求LightService.
mSystemServiceManager.startService(BatteryService.class);
//跟踪应用程序使用统计.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// UsageStatsService有效后更新, 需要在performBootDexOpt之前.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
//跟踪可更新的WebView 是否处于就绪状态 并且监视更新安装
mSystemServiceManager.startService(WebViewUpdateService.class);
}
最后启动其他所有的服务:
/**启动其他五花八门还没有重构和组织的服务
* .
*/
private void startOtherServices() {
final Context context = mSystemContext;
AccountManagerService accountManager = null;
ContentService contentService = null;
VibratorService vibrator = null;
IAlarmManager alarm = null;
IMountService mountService = null;
NetworkManagementService networkManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
NetworkScoreService networkScore = null;
NsdService serviceDiscovery= null;
WindowManagerService wm = null;
UsbService usb = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
CommonTimeManagementService commonTimeMgmtService = null;
InputManagerService inputManager = null;
TelephonyRegistry telephonyRegistry = null;
ConsumerIrService consumerIr = null;
AudioService audioService = null;
MmsServiceBroker mmsService = null;
EntropyMixer entropyMixer = null;
CameraService cameraService = null;
boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime", false);
boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
try {
Slog.i(TAG, "Reading configuration...");//打印“读取配置。。。”
SystemConfig.getInstance();//获取SystemConfig对象
traceBeginAndSlog("StartSchedulingPolicyService");
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());//调度策略
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...略
StatusBarManagerService statusBar = null;//状态条
INotificationManager notification = null;//通知
InputMethodManagerService imm = null;//输入工具
WallpaperManagerService wallpaper = null;//壁纸
LocationManagerService location = null;//位置
CountryDetectorService countryDetector = null;//国家
TextServicesManagerService tsms = null;//text
LockSettingsService lockSettings = null;//锁屏设置
AssetAtlasService atlas = null;//资产阿特拉斯
MediaRouterService mediaRouter = null;//媒体路由
// Bring up services needed for UI.
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
traceBeginAndSlog("StartInputMethodManagerService");
try {
imm = new InputMethodManagerService(context, wm);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
reportWtf("starting Input Manager Service", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("StartAccessibilityManagerService");
try {
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
new AccessibilityManagerService(context));
} catch (Throwable e) {
reportWtf("starting Accessibility Manager", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
}
...略
// These are needed to propagate to the runnable below.
final NetworkManagementService networkManagementF = networkManagement;
final NetworkStatsService networkStatsF = networkStats;
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
final NetworkScoreService networkScoreF = networkScore;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
final TextServicesManagerService textServiceManagerServiceF = tsms;
final StatusBarManagerService statusBarF = statusBar;
final AssetAtlasService atlasF = atlas;
final InputManagerService inputManagerF = inputManager;
final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
final MediaRouterService mediaRouterF = mediaRouter;
final AudioService audioServiceF = audioService;
final MmsServiceBroker mmsServiceF = mmsService;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PhaseActivityManagerReady");
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartObservingNativeCrashes");
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Slog.i(TAG, "WebViewFactory preparation");
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "WebViewFactoryPreparation");
WebViewFactory.prepareWebViewInSystemServer();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeMountServiceReady");
try {
if (networkScoreF != null) networkScoreF.systemReady();
} catch (Throwable e) {
reportWtf("making Network Score Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
。。。略
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
});
}
//启动系统UI
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}
在不同的进程中运行的系统服务之间的通信方式为Binder。
观察上面的启动服务的代码,最普遍的有三种方式启动系统服务,比如:
//通过SystemServiceManager.startService进行启动:
mSystemServiceManager.startService(TelecomLoaderService.class);//传入类名
private static final String WIFI_SERVICE_CLASS =
"com.android.server.wifi.WifiService";
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);//传入字符串
//通过ServiceManager.addService启动:
networkManagement = NetworkManagementService.create(context);
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);//传入Context中定义的变量名,服务
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);//传入字符串,服务
//其他:
if (audioServiceF != null) audioServiceF.systemReady();
if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
SystemServiceManager是一个管理com.android.server.SystemService 系统服务创建,启动,和一些生命周期事件的类。
先看SystemServiceManager.startService方法,此方法名有两个个方法体,一个出入参数为字符串,一个传入参数为Class类名,方法分别如下:
/**
* 通过类名启动一个服务.
*
* @return 服务对象.
*/
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
final Class<SystemService> serviceClass;//SystemService子类
try {
serviceClass = (Class<SystemService>)Class.forName(className);//返回的是一个类,作用是要求JVM查找并加载指定的类
} 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);//再执行下面的startService方法,并返回值
}
// Services that 应该接受生命周期事件.
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
/**
* 创建和启动一个系统服务.
* 这个类必须是{@link com.android.server.SystemService}的子类.
*
* @param serviceClass 实现SystemService接口的java类.
* @return 返回服务对象,不可以为null.
* @throws RuntimeException 启动失败抛出异常.
*/
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();//获得类的名字
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// 创建service对象.
//isAssignableFrom是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的超类或接口
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());//服务必须extendSystemService
}
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);//注册服务,添加到ArrayList<SystemService> mServices中
// 启动服务.
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;//返回服务
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
可以看出这两个方法执行的系统服务类都是SystemService的子类。在第二个方法中,先是判断这个服务是不是SystemService的子类,,然后我们创建服务的对象,再通过添加到服务列表添加到ArrayList mServices中,并且同时通过调用SystemService.onStart()方法对这个启动的服务进行相关配置。onStart()方法由SystemService的子类实现,就是启动哪个服务就调用哪个服务类里的onStart()方法,比如BatteryService服务类:
@Override
public void onStart() {
IBinder b = ServiceManager.getService("batteryproperties");//获取属性配置
final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
IBatteryPropertiesRegistrar.Stub.asInterface(b);
try {
batteryPropertiesRegistrar.registerListener(new BatteryListener());//注册电量监听
} catch (RemoteException e) {
// Should never happen.
}
publishBinderService("battery", new BinderService());
publishLocalService(BatteryManagerInternal.class, new LocalService());
}
然而我们此时可以发现SystemServiceManager.startService方法只是加载了系统服务,并没有启动,仔细阅读SystemServer类我们会发现,代码每执行一段后会执行如下方法:
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
startBootPhase方法作用是启动执行到这儿的这一阶段的所有系统服务,参数为SystemService中定义的常量:
/*
* 开机阶段
*/
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
/**
* 到了这儿, 可以接受锁屏状态下的数据.
*/
public static final int PHASE_LOCK_SETTINGS_READY = 480;
/**
* 到了这儿, 服务可以安全的和核心系统服务交互.
*/
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
/**
*到了这儿,服务可以接受广播Intents.
*/
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
/**
* 到了这儿,服务可以启动/绑定第三方apps.
*/
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
/**
* 当收到这个启动指令, 服务允许用户与设备交互.设备开机完成并且启动了桌面应用
*/
public static final int PHASE_BOOT_COMPLETED = 1000;
SystemServiceManager.startBootPhase方法为:
/**启动执行到这儿的这一阶段的所有系统服务
* @param phase The boot phase to start.
*/
public void startBootPhase(final int phase) {
if (phase <= mCurrentPhase) {//是否小于当前的阶段常量值
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
Slog.i(TAG, "Starting phase " + mCurrentPhase);
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);
final int serviceLen = mServices.size();//获取mServices的大小
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);//获取服务
try {
service.onBootPhase(mCurrentPhase);//调用SystemService.onBootPhase()方法启动
} catch (Exception ex) {
throw new RuntimeException("Failed to boot service "
+ service.getClass().getName()
+ ": onBootPhase threw an exception during phase "
+ mCurrentPhase, ex);//启动失败抛出异常,在mCurrentPhase阶段
}
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
这里又调用了SystemService.onBootPhase()方法的实现方法,比如启动到了BatteryService服务,BatteryService.onBootPhase():
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
// check our power situation now that it is safe to display the shutdown dialog.
synchronized (mLock) {
ContentObserver obs = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
synchronized (mLock) {
updateBatteryWarningLevelLocked();
}
}
};
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, obs, UserHandle.USER_ALL);
updateBatteryWarningLevelLocked();
}
}
}
/**
* 放进service manager 中@a service called @a name .
*
* @param name 新service的名字
* @param service service对象
*/
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
getIServiceManager()如下,返回的是一个IServiceManager对象:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 查找service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
查找service manager中调用了ServiceManagerNative.asInterface():
/**
* 将一个Binder对象转换成一个 service manager接口;生成一个代理,如果需要.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
//查询本地是否有IServiceManager
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);//queryLocalInterface(descriptor)返回值是IInterface类型,其是IServiceManager的父接口
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);//如果没有则返回ServiceManagerProxy对象
}
此时可得getIServiceManager().addService()就是ServiceManagerProxy.addService():
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
/准备Parcel数据
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
//获取结果
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
//回收对象的引用
reply.recycle();
data.recycle();
}
ServiceManager相关类关系图:
如果简单来说,这里一部分类之间使用了代理模式:
代理模式:为其它对象提供一种代理以控制对这个对象的访问。
1,抽象接口IServiceManager:它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。
2,代理类ServiceManagerNative:它包含了对真实类的引用,从而可以在任何时候操作真实类对象;在代理类中提供一个可以使用的接口,以便在任何时候都可以替代真实类,供客户端使用;代理类还可以控制对真实类的使用,负责在需要的时候创建和删除真实类对象,并对真实类对象的使用加以约束。通常,在代理类中,客户端在调用所引用的真实类操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实类对象中的操作。
对真实类的引用,控制对真实类的访问:如果本地已经缓存有了,使用本地的,否则调用真实类ServiceManagerProxy的对象:
/**
* 将一个Binder对象转换成一个 service manager接口;.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);//查询本地是否有IServiceManager
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);//如果没有则返回ServiceManagerProxy对象
}
构造器,以便在任何时候都可以替代真实类,供客户端使用
public ServiceManagerNative()
{
//Binder.attachInterface(IInterface owner, String descriptor)
attachInterface(this, descriptor);
}
3,真实类ServiceManagerProxy:它定义了代理类所代表的真实对象,在真实类中实现了真实的业务操作,客户端可以通过代理类间接调用真实类中定义的操作。
构造器:
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
4,客户端ServiceManager对抽象接口进行编程:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 调用代理类ServiceManagerNative的asInterface方法
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
这个方法的使用上面已经陈述过了。
android源码中使用代理模式的地方很多,尤其是系统服务方面,因为需要使用Binder才能与系统服务进行通信,等等。
代理模式效果与适用场景
代理模式是常用的结构型设计模式之一,它为对象的间接访问提供了一个解决方案,可以对对象的访问进行控制。代理模式类型较多,其中远程代理、虚拟代理、保护代理等在软件开发中应用非常广泛。
模式优点
(1) 能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
(2) 客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵活性和可扩展性。
此外,不同类型的代理模式也具有独特的优点,例如:
(1) 远程代理为位于两个不同地址空间对象的访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率。
(2) 虚拟代理通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,可以在一定程度上节省系统的运行开销。
(3) 缓冲代理为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。
(4) 保护代理可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。
模式缺点
(1) 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。
(2) 实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂,例如远程代理。
代理模式的类型较多,不同类型的代理模式有不同的优缺点,它们应用于不同的场合:
(1) 当客户端对象需要访问远程主机中的对象时可以使用远程代理。
(2) 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。
(3) 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。
(4) 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。
(5) 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。
使用系统服务需要跨进程通信,而android已经为我们封装好了,应用程序可以通过系统提供的Manager接口来访问这些Service提供的数据。比如通常使用的Context.getSystemService()来获取系统服务,Context中定义了大部分标识系统服务的常量。比如:
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
追溯获取系统服务过程:
ContextImpl.getSystemService():
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry.getSystemService(this, name):
/**
* 从给定的context获取系统服务.
*/
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);//从ServiceFetcher中查找服务
return fetcher != null ? fetcher.getService(ctx) : null;//如果fetcher不为空返回fetcher.getService(ctx)
}
ServiceFetcher是一个接口,fetcher.getService(ctx)的实现是实现ServiceFetcher类,有三个,都是SystemServiceRegistry的内部类,getService(ctx)返回的是使用的服务对象,比如我们要使用AccessibilityManager,返回的是AccessibilityManager对象:
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
AccessibilityManager.getInstance(ctx):
/**
* 获得一个AccessibilityManager 对象 (create one if necessary).
*
* @param context Context in which this manager operates.
*
* @hide
*/
public static AccessibilityManager getInstance(Context context) {
synchronized (sInstanceSync) {
if (sInstance == null) {
final int userId;
if (Binder.getCallingUid() == Process.SYSTEM_UID//进程UID
|| context.checkCallingOrSelfPermission(//检查权限
Manifest.permission.INTERACT_ACROSS_USERS)
== PackageManager.PERMISSION_GRANTED
|| context.checkCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL)
== PackageManager.PERMISSION_GRANTED) {
userId = UserHandle.USER_CURRENT;
} else {
userId = UserHandle.myUserId();
}
IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
IAccessibilityManager service = iBinder == null
? null : IAccessibilityManager.Stub.asInterface(iBinder);//取得AccessibilityManagerService
sInstance = new AccessibilityManager(context, service, userId);//创建服务对象
}
}
return sInstance;
}
可以看到最终是ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)获取一个iBinder对象,然后通过AIDL获得系统服务AccessibilityManagerService,最后通过构造器得到一个AccessibilityManager对象。ServiceManager.getService方法:
/**
* 根据名字返回一个服务的引用(a reference to a service).
*
* @param name the name of the service to get
* @return a reference to the service, or <code>null</code> if the service doesn‘t exist
*/
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
getIServiceManager().getService(name)是ServiceManagerProxy.getService(String name):
public IBinder getService(String name) throws RemoteException {
//获取Parcel数据
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
//发送请求
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
//获取结果
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
大部分服务都可以用Context.getSystemService()获取,但也有小部分不是通过Context.getSystemService()获取的,比如:
PackageManager mPackageManager = SystemContext.getPackageManager();//获取PackageManager
ResourcesManager mResourcesManager = ResourcesManager.getInstance();//获取ResourcesManager
。。。
明白了使用系统服务调用方法的步骤,对在开发中使用系统服务有很大便利,比如最常见的拦截电话,正常情况下是不能够通过代码自动挂断电话的,但通过调用电话本地服务的隐藏方法endCall()则可以,关键步骤如下(上面系统服务和启动系统服务相关的类都是隐藏的):
Class clazz=Class.forName("android.os.ServiceManager");//获取类ServiceManager
Method method=clazz.getMethod("getService",String.class);//获取方法getService
IBinder binder= (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE);
ITelephony iTelephony = ITelephony.Stub.asInterface(binder);//获取服务对象
iTelephony.endCall();//调用服务中的方法,挂断电话
标签:
原文地址:http://blog.csdn.net/u012585964/article/details/52290940