Android 系统服务
Posted 迷途小书童Eric
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 系统服务相关的知识,希望对你有一定的参考价值。
android系统服务大致分为三大类:本地守护进程、Native系统服务和Java系统服务。如下图所示:
本地守护进程
init进程根据init.rc文件中的定义,启动本地守护进程。这些进程会常驻在系统中,有的只会启动一次,有的如果退出了,还会被init启动。具体的启动方式就在init.rc中定义。
下面大体列举几个守护进程及其功能。
守护进程 | 功能 |
---|---|
vold | 管理存储设备,自动安装存储设备,将设备分区格式化 |
netd | 管理蓝牙、wifi、usb等各种网络连接 |
installd | 负责安装及卸载软件包,确认软件包的完整性 |
rild | 接收来自于phone应用程序或其他客户端程序发出的调制解调控制请求,并传递给调制解调器 |
adbd | 提供可以调试Android的环境 |
servicemanager | binder通信大管家 |
surfaceflinger | 负责android系统的UI图形显示 |
mediaserver | 负责播放音频、视频,camera拍照录像 |
Native系统服务
由c++语言编写,运行在本地守护进程中。比如mediaserver守护进程中就包含AudioFlinger、MediaPlayerService、CameraService、AudioPolicyService和SoundTriggerHwService等服务。在
mediaserver进程的main函数中,初始化这些服务的实例,代码如下:
int main(int argc __unused, char** argv)
{
...
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
SoundTriggerHwService::instantiate();
...
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
在所属进程初始化的时候会将Native系统服务注册到ServiceManager中。这样,其他的应用或服务就可以通过binder机制调用Native系统服务了。
当然,我们也可以自己开发一个Native系统服务,实现其Binder接口,这样Native层的其他应用或服务就可以调用该服务了。
如果我们开发的Native系统服务想提供给Java层应用使用,就需要实现一个Java接口,然后通过JNI调用Native系统服务。
Java系统服务
由Java语言编写,大部分运行在system_server进程中。每个系统服务都以线程的形态运行,等待应用程序发出的请求,然后对请求进程处理,再讲结果返回给应用程序。
这部分系统服务又可以分为两种:Java核心系统服务和Java硬件系统服务。
Java核心系统服务是Android系统正常运转的基础,包括大家所熟知的AMS、WMS、PMS等。
Java硬件服务是为应用提供硬件控制服务,如电话服务、wifi服务、PowerManagerService等。
下面罗列了运行在system_server中的系统服务,按字母排序。
AccessibilityManagerService 截获用户输入,并根据输入给用户一些额外的反馈,起到辅助效果的服务
AccountManagerService 管理设备中所有账号的服务,包括账号、密码、授权管理功能
ActivityManagerService 管理所有组件的服务,安卓系统的核心服务 AlarmManagerService 管理闹钟的服务
AppWidgetService 管理APP widgets的工作,包括加载、删除、布局等
AssetAtlasService 将一些系统图片资源合并成一个纹理图传给GPU达到硬件加速的效果的服务
Audioservice 管理音频的服务
BackupManagerService 管理备份和应用数据的服务
BatteryService 管理电池的服务
BluetoothManagerService 管理系统蓝牙的服务
CertBlacklister 更新系统SSL证书的公共秘钥和序列号黑名单的服务
ClipboardService 管理系统剪贴板的服务
CommonTimeManagementService 管理公共时间配置的服务
ConnectivityService 管理网络连接的服务
ContentService 管理系统数据更新通知的服务,和ContentProvider密切相关
CountryDetectorService 检测当前系统所属国家的服务
DevicePolicyManagerService 管理系统设备配置的服务
DeviceStorageMonitorService 管理系统存储空间的服务,当存储空间小于某个阈值时,会发出警告广播
DiskStateService 管理系统存储空间统计的服务
DisplayManagerService 管理显示设备的服务
DreamManagerService 管理屏幕保护的服务
DropBoxManagerService 生成和管理系统运行中日志文件的服务
EntropyMixer 加载和保存随机信息的服务
IdleMaintenanceService 管理系统在空闲时执行维护任务的服务
InputManagerService 管理触屏输入的服务
InputMethodManagerService 管理系统输入法的服务
LightsService 管理光传感器的服务
LocationManagerService 管理定位和位置的服务
LockSettingsService 管理系统锁屏设置的服务
MountService 管理系统存储设备挂载和卸载的服务
NetWorkManagementService 管理系统网络的服务
NetWorkPolicyManagerService 管理网络连接策略的服务
NetWorkStatsService 管理网络连接状态的服务
NetWorkTimeUpdateService 根据网络时间更新本地时间的服务
NotificationManagerService 管理系统通知的服务
PackageManagerService 管理应用包的服务
PowerManagerService 管理系统电源的服务
PrintManagerService 管理打印的服务
RecognitionManagerService 管理身份识别的服务
SamplingProfilerService 记录和分析系统启动性能的服务
SchedulingPolicyService 管理系统调度策略的服务
SearchManagerServcie 管理系统搜索功能的服务
SerialServie 管理系统串口设备的服务
StatusBarManagerService 管理系统状态栏的服务
TelephonyRegistry 监听和管理通话事件和状态的服务
TextServicesManagerService 文本拼写检查的服务
UiModeManagerService 设置和管理系统UI模式的服务
UsbService 管理USB连接的服务
UserManagerService 管理系统用户身份信息的服务
VibratorService 管理系统振动器的服务
WallpaperManagerService 管理系统桌面背景墙纸的服务
WifiP2pService 管理Wifi点对点连接的服务
WifiService 管理系统Wifi设备的服务
WindowManagerService 管理窗口的服务,安卓系统的核心服务
Java系统服务的实现
从在android5.1.1中,Java Service一般都会继承一个虚类SystemService,在其中定义了两个接口onStart和onBootPhase。
- onStart() :Java Service启动的时候会回调该函数。
- onBootPhase() : 系统启动的各个阶段会回调该函数。
这样,启动服务就很简单了:
mSystemServiceManager.startService(xxxxxxService.class);
我们继续看一下startService的实现:
public class SystemServiceManager {
// 保存所有SystemService
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
//调用JVM加载className指定的类,会执行该类的静态代码段
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
...
}
...
mServices.add(service); // 添加该service
try {
service.onStart(); // 回调该service的onStart方法
} catch (RuntimeException ex) {
...
}
...
}
}
下面看一下onBootPhase回调方法。
在system启动的一些阶段,系统会调用如下代码,主动回调SystemService的onBootPhase方法。
mSystemServiceManager.startBootPhase(SystemService.PHASE_XXXXXX);
public class SystemServiceManager {
public void startBootPhase(final int phase) {
// 阶段值会随着系统启动的进行越来越大,因此下一个阶段值肯定要大于当前阶段
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase; //保存当前阶段
// 遍历所有的SystemService,并回调它的onBootPhase方法。
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
try {
service.onBootPhase(mCurrentPhase); // 将阶段值也传进去
} catch (Exception ex) {
...
}
}
}
}
PHASE_XXXXXX指示了各个不同的启动阶段,定义如下:
public abstract class 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;
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
public static final int PHASE_BOOT_COMPLETED = 1000;
}
所以,在onBootPhase(int phase)中,我们可以根据phase中指示的启动阶段,做不同的操作!在自己设计新的系统服务时,这个很重要。因为一些操作需要系统环境的支持,有了这个回调函数及phase参数,我们就可以在合适的阶段做合适的操作了。
另外,Java系统服务中一般还会实现一个方法:systemReady()。该方法在SystemServer.java–>startOtherServices()调用:
final XXXService xxxService;
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
try {
if (xxxService != null) xxxService.systemReady();
} catch (Throwable e) {
reportWtf("making XXX Service ready", e);
}
...
}
}
在[Android5.1]ActivityManagerService启动过程分析中,我们知道AMS的systemReady方法会回调这个Runnable,上述代码就会执行。
注意:Java系统服务的onStart、onBootPhase、systemReady等方法,都运行在system_server主线程中。建议新建一个线程来处理复杂、耗时操作。
Java系统服务Binder通信
上面讲了Java系统服务的实现,随之而来的一个问题是,其他服务或应用怎么调用Java系统服务的功能?当然是通过Binder通信。
下面就讲一下Java系统服务的Binder服务实现。假设服务名为ExampleService。
首先,需要新建和实现三个文件:
frameworks/base/core/java/android/app/IExample.aidl
frameworks/base/core/java/android/app/Example.java
frameworks/base/services/core/java/android/server/ExampleService.java
frameworks/base/core/java/android/app/IExample.aidl代码如下:
interface IExample {
boolean helloWorld(String str);
}
frameworks/base/core/java/android/app/Example.java代码如下:
class Example {
private final IExample mService;
Example(Context context, IExample service) {
mService = service;
}
public boolean helloWorld(String str) {
try {
return mService.helloWorld(str);
} catch(RemoteException e) {
return null;
}
}
}
frameworks/base/services/core/java/android/server/ExampleService.java代码如下:
class ExampleService extends SystemService {
private Context mContext;
public ExampleService(Context context) {
super(context);
mContext = context;
}
@Override
public void onStart() {
publishBinderService(Context.EXAMPLE_SERVICE, new BinderService());
}
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_SYSTEM_SERVICES_READY) {
...
}
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
...
}
if (phase == PHASE_BOOT_COMPLETED) {
...
}
...
}
public void systemReady() {
...
}
class BinderService extend IExample.Stub {
@Override
boolean helloWorld(String str) {
...
}
}
}
其次,修改如下文件的代码:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/content/Context.java
frameworks/base/core/java/android/app/SystemServiceRegistry.java
- frameworks/base/services/java/com/android/server/SystemServer.java修改如下:
import com.android.server.ExampleService;
public final class SystemServer {
ExampleService mExampleService = null;
...
private void startOtherServices() {
...
mExampleService = mSystemServiceManager.startService(ExampleService.class);
...
try {
if (mExampleService != null) mExampleService.systemReady();
} catch (Throwable e) {
reportWtf("making Example Service ready", e);
}
...
}
- frameworks/base/core/java/android/content/Context.java修改如下:
public abstract class Context {
...
public static final String EXAMPLE_SERVICE = "example";
...
}
- frameworks/base/core/java/android/app/SystemServiceRegistry.java修改如下:
final class SystemServiceRegistry {
...
registerService(Context.EXAMPLE_SERVICE, Example.class,
new CachedServiceFetcher<Example>() {
@Override
public Example createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.EXAMPLE_SERVICE);
IExample service = IExample.Stub.asInterface(b);
if (service == null) {
Log.wtf(TAG, "Failed to get Example Service.");
}
return new Example(ctx.getOuterContext(),service);
}});
...
}
最后,其他应用或服务通过binder调用ExampleService的helloWorld方法,代码如下:
import android.app.Example;
class Client {
static Example mService;
mService = (Example) context.getSystemService(Context.EXAMPLE_SERVICE);
mService.helloWorld(str);
}
以上是关于Android 系统服务的主要内容,如果未能解决你的问题,请参考以下文章
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段