Android framework add service

本文介绍在Android系统中添加自定义系统服务的过程,包括撰写AIDL文件、注册服务到SystemServer等步骤,以及如何在应用程序中调用这些服务。

From here

Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等。下面描述一下添加一个系统服务的具体步骤。


1、  撰写一个aidl文件,定义服务的接口,将在编译过程中通过aidl工具生成对应的java接口。一般系统服务的aidl文件都放在framework\base\core\java\android\os目录中。

以我所写的IMyTool.aidl为例。在.aidl中定义自己需要加入的方法,编写规则和java接口差不多,这里不多说。


2、  将aidl文件名添加到frameworks\base\目录下的Android.mk编译脚本文件中。

如:

LOCAL_SRC_FILES += \

         core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl\

         …\

         core/java/android/os/IMyTool.aidl\

         …

IMyTool.aidl即我加进去的aidl文件,加入后才能在make过程中编译到,否则将在后面的SystemServer添加系统服务时会报错提示找不到对应类。


3、  编写真正工作的服务类,继承IMyTool.Stub类(AIDL文件名.Stub,aidl生成的接口中的内部类,是一个Binder)。

服务类一般都放在framework\base\services\java\com\android\server目录中。

例如:

public class MyToolService extends IMyTool.Stub {

           实现IMyTool.aidl中定义的接口。

}


4、  将自定义服务注册到SystemServer,使得开机过程中被添加。

在framework\base\services\java\com\android\server目录中的SystemServer中启动服务代码处加入:

try {

           Slog.i(TAG, "MyToolService");

           ServiceManager.addService(Context.MY_TOOL_SERVICE,new MyToolService(context));// MyToolService构造函数自己定义,一般都会用到Context

} catch(Throwable e) {

           Slog.e(TAG, "Failure startingMyToolService", e);

}

上面代码中Context.MY_TOOL_SERVICE是自己在Context类中定义的常量,也就是给服务定义的名字,使用常量方便获取服务,而不需要记住注册服务时用的名字,且想换名字时只需改一个常量的值。

5、  由于在工程中添加了自己定义的类及常量,系统的api没有更新,因此需要先在工程中make clean然后make update-api,执行完后会发现frameworks\base\api\current.xml文件中多出自己定义的一些东西。current.xml这个文件包含了所有系统所有能被应用层使用的类及其方法等。

之后再使用make编出来的固件及jar包就能包含自定义的接口。



编译后如何使用:

将编出来的jar包通过lib方式导入工程。jar包位置:out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes.jar

调用以下代码获取自定义服务:

IMyTool myTool = IMyTool.Stub.asInterface(ServiceManager.getService(MY_TOOL_SERVICE));

MY_TOOL_SERVICE即在Context中定义的常量。获取到myTool后就可以调用在aidl文件中定义的接口了。



From here

为Android添加Java层服务

 

同前一篇文章类似,此文旨在简单介绍一下如何在java层添加自己的服务,相关的理论网上已经有很多文章,在此不在详述。

Java层服务顾名思义即为从Java层提供的服务,它与C++层的服务不同之处在于其服务进程的运行由系统(ServiceManager)统一维护。在文件frameworks/base/services/java/com/android/server/SystemServer.java中我们可以看到以下代码:

AlarmManagerServicealarm= new AlarmManagerService(context);

ServiceManager.addService(Context.ALARM_SERVICE,alarm);

 

这个操作在系统启动时完成,由ServiceManager负责创建服务进程并运行之。所以我们要做的事就是实现一个java服务,并将其添加到这里并由系统运行起来,以下是具体实现步骤:

 

 

实现自己的java层service

1.      在目录

frameworks/base/core/java/android/os中增加自己的AIDL文件用来申明服务:

BelyService.aidl:

package android.os;

interface IBelyService {

        /**

        *

        */

        int calculateSqu(int value);

}

2.      在目录

frameworks/base/services/java/com/android/server增加service的实现文件:

BelyService.java:

package com.android.server;

import android.content.Context;

import android.os.IBelyService;

public class BelyService extends IBelyService.Stub {

        publicBelyService(Context context){

               super();

        }

        publicint calculateSqu(int val){

               return val*val;

        }

}

 

3.      将java服务添加到ServiceManager中:

BelyService bs = new BelyService(context);

ServiceManager.addService("BelyService",bs);

 

自此,重新编译Android并运行,我们所创建的服务即可访问,下面是演示如何调用:

同样在package/apps下任意创建一个应用,调用服务的方法如下:

import android.os.ServiceManager;

import android.os.IBelyService;

IBelyService bs =IBelyService.Stub.asInterface(ServiceManager.getService("BelyService"));

int ret = bs.calculateSqu(9);

 

上面我们使用的是Android内部的方法来获取服务,当然也可以使用公开的API:context.getSystemService来获取。

谢谢!


Android 的窗口系统(Window System)是 Android Framework 中非常核心的一部分,它负责管理所有应用界面的显示、输入事件的传递、窗口层级(Z-order)、动画、焦点控制等。这个系统的核心组件包括: - `WindowManagerService`(WMS) - `SurfaceFlinger` - `ViewRootImpl` - `WindowManager` - `LayoutParams` - `DisplayManager` - `InputManager` --- ## 🧱 Android 窗口系统架构概览 整个窗口系统涉及从 Framework 到 Native 层的多个组件,主要流程如下: ``` App (Activity/Dialog/Toast) → WindowManager.addView() → ViewRootImpl.setView() → WMS.addWindow() → SurfaceFlinger 创建 Surface 并合成 ``` --- ## 🧩 核心组件详解 ### 1. **WindowManager** 是应用层访问窗口系统的入口,每个 `Activity` 都有一个 `WindowManager` 实例。 ```java WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); ``` ### 2. **WindowManager.LayoutParams** 用于描述一个窗口的属性,包括: - 类型(TYPE) - 标志(FLAG) - 软件层类型(LAYOUT_IN_SCREEN、LAYOUT_NO_LIMITS) - 宽高(MATCH_PARENT / WRAP_CONTENT / 具体像素) 示例: ```java WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ); ``` ### 3. **WindowManagerService (WMS)** 运行在 System Server 进程中,负责管理所有窗口的添加、移除、层级排序、焦点控制、窗口动画等。 关键职责: - 维护窗口层级(Z-order) - 管理窗口的显示属性 - 接收来自 `WindowManager` 的请求(如 addView) - 与 `SurfaceFlinger` 通信,控制窗口的绘制 ### 4. **SurfaceFlinger** Native 层组件,负责将所有窗口的 Surface 合成到屏幕上。 - 每个窗口都有一个 `Surface` - SurfaceFlinger 接收来自 WMS 的 Surface 描述,进行合成 - 支持硬件加速(GPU、HWC) ### 5. **ViewRootImpl** 连接 View 系统与 WMS 的桥梁。每个窗口都有一个 `ViewRootImpl`,它负责: - 与 WMS 通信,添加/更新窗口 - 处理 View 的测量、布局、绘制 - 处理输入事件(InputEvent) ### 6. **DisplayManager** 管理显示设备(如主屏、外接显示器),负责创建 `Display` 对象。 --- ## 📦 窗口类型(Window Types) 窗口类型决定了窗口的层级和用途: | 类型 | 描述 | |------|------| | `TYPE_APPLICATION` | 普通 Activity 窗口 | | `TYPE_APPLICATION_PANEL` | Dialog、PopupWindow | | `TYPE_SYSTEM_ALERT` | 系统级悬浮窗(需要权限)| | `TYPE_PHONE` | 电话窗口 | | `TYPE_NAVIGATION_BAR` | 导航栏 | | `TYPE_STATUS_BAR` | 状态栏 | ⚠️ **注意:** 一些窗口类型需要特殊权限,如 `SYSTEM_ALERT_WINDOW`,需要用户授权。 --- ## 🖼️ 窗口绘制流程 1. 应用调用 `setContentView()`,创建 `PhoneWindow` 和 `DecorView` 2. `ViewRootImpl` 被创建并调用 `setView()`,通过 Binder 通知 WMS 添加窗口 3. WMS 创建窗口对象并分配 `Surface` 4. `ViewRootImpl` 调用 `performTraversals()`,触发 `measure`, `layout`, `draw` 5. `draw()` 会将内容绘制到 `Surface` 上 6. `SurfaceFlinger` 合成所有窗口并输出到屏幕 --- ## 🧪 示例:添加一个悬浮窗口 ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.canDrawOverlays(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, 0); } } WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ); TextView textView = new TextView(this); textView.setText("悬浮窗口"); wm.addView(textView, params); ``` --- ## ✅ 总结 | 组件 | 职责 | |------|------| | `WindowManager` | 应用侧 API,添加/移除窗口 | | `WindowManager.LayoutParams` | 设置窗口属性 | | `WindowManagerService` | 系统服务,管理窗口生命周期和层级 | | `SurfaceFlinger` | 合成窗口内容,输出到屏幕 | | `ViewRootImpl` | View 与 WMS 的通信桥梁 | | `DisplayManager` | 管理显示设备 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值