Android -- 使用Binder API实现一个简单服务

Android Binder实现浅析-Binder驱动 简介 Android是如何实现跨进程通信的,大家熟悉的Binder是什么,怎么设计的,进程间的数据如何发送接收的。本文将以及解析,并对Binder驱动实现、Native层实现、Java层实现三块做一个总结分析。 Binder学习思路 Binder与传统IPC的区别 Binder驱动的内部设计、数据结构 Binder驱动与应用程序进程(C/S)之间的通信过程 Android应用程序通过Binder... 阅读详情

Android -- 使用Binder API实现一个简单服务


在上一篇博客中,我们借助ServiceManager从源码的角度简要分析了一下Binder的使用机制;接下来,我们就可以按照ServiceManager的实现套路,实现一个自己的Binder服务。

先列出代码目录结构:

1、服务业务接口:/mybinder/extra/IMyService.cpp
                             /mybinder/extra/IMyService.h
2、Server组件接口:/mybinder/server/IMyServer.cpp

                              /mybinder/server/Android.mk
3、Client组件接口:/mybinder/client/IMyClient.cpp

                             / mybinder/client/Android.mk


下面直接上源代码。

一、业务接口代码

IMyService.h:

#ifndef  _MY_SERVICE_
#define	_MY_SERVICE_

#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/String16.h>

#define MY_SERVICE "coder.core.MyService"

using namespace android;

//定义业务函数接口,声明DECLARE_META_INTERFACE()宏模板函数
class IMyService : public IInterface
{
public:
DECLARE_META_INTERFACE(MyService);
public:
virtual void sendInt(int32_t val) = 0;
virtual String8 getString() = 0;
public:
//业务函数的标号,用以区分是调用哪个业务,值对应的就是onTransact()、transact()
//中的code参数,用在switch...case...判断中
enum{
SEND_INT = IBinder::FIRST_CALL_TRANSACTION,
GET_STRING
};
};

//定义Server组件
class BnMyService : public BnInterface<IMyService>
{
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};

#endif
IMyService.cpp:
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include "IMyService.h"

class BpMyService : public BpInterface<IMyService>
{
public:
BpMyService(const sp<IBinder>& impl) : BpInterface<IMyService>(impl){}
public:
void sendInt(int32_t val){
Parcel data, reply;
data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
data.writeInt32(val);

remote()->transact(SEND_INT, data, &reply);
}

String8 getString(){
Parcel data, reply;
data.writeInterfaceToken(IMyService::getInterfaceDescriptor());

remote()->transact(GET_STRING, data, &reply);
String8 res = reply.readString8();
return res;
}
};

//实现IMPLEMENT_META_INTERFACE()宏模板函数
IMPLEMENT_META_INTERFACE(MyService, MY_SERVICE);

status_t BnMyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code){
case SEND_INT:
{
CHECK_INTERFACE(IMyService, data, reply);
int32_t val = data.readInt32();//去除传入的参数,调用服务类的函数
sendInt(val);

return NO_ERROR;
}
break;
case GET_STRING:
{
CHECK_INTERFACE(IMyService, data, reply);
String8 res = getString();//调用服务类的函数
reply->writeString8(res);//将结果存入reply,BpMyService端可以读出该结果

return NO_ERROR;
}
break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
};

二、Server组件代码

MyServer.cpp:
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

#include "../extra/IMyService.h"

class MyService : public BnMyService
{
public:
MyService(){option = 0;}
virtual ~MyService(){}
public:
static void instance(){
defaultServiceManager()->addService(String16(MY_SERVICE), new MyService());
}

void sendInt(int32_t val)
{
option = val;
}

String8 getString()
{
if(option <= 0)
return String8("you may not set val, or the value you set is <= 0.");
else
return String8("you have set the option with the value > 0.");

return String8("this is default string value.");
}
private:
int32_t option;
};

int main(int argc, char** argv)
{
//注册MyService服务到系统中
MyService::instance();

//开启线程池,接收处理Client发送的进程间通信请求
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();

return 0;
}
Server组件编译的Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGSS := optional
LOCAL_SRC_FILES := ../extra/IMyService.cpp \
					MyServer.cpp
LOCAL_SHARED_LIBRARIES := libcutils libutils libbinder
LOCAL_MODULE := MyService
include $(BUILD_EXECUTABLE)

三、Client组件代码

MyClient.cpp:

#include <binder/IServiceManager.h>
#include "../extra/IMyService.h"

int main()
{
sp<IBinder> binder = defaultServiceManager()->getService((String16(MY_SERVICE));
if(binder == NULL){
printf("Failed to get the MyService binder object.\n");
return -1;
}

sp<IMyService> service = IMyService::asInterface(binder);
if(service == NULL){
printf("Failed to get the MyService service.\n");
return -1;
}

String8 str1 = service->getString();
printf("we get string value: %s \n",str1.string());

service->sendInt(2);
String8 str2 = service->getString();
printf("we get string value: %s\n",str2.string());
}
Client组件编译的Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGSS := optional
LOCAL_SRC_FILES := ../extra/IMyService.cpp \
					MyClient.cpp
LOCAL_SHARED_LIBRARIES := libcutils libutils libbinder
LOCAL_MODULE := MyClient
include $(BUILD_EXECUTABLE)

代码组织完成后,我们可以将工程目录放到源码的external/目录下,使用mmm命令将Server组件、Client组件编译成两个可执行文件来运行、验证。

我们需要先运行Server组件,再运行Client组件;平台上验证的效果如图所示:


再附一张这个简单服务的类继承关系图:


由于公司办公电脑限制,即使是自己写的一些demo程序都会被加密,在外部电脑上无法正常查看;所以,在公司平台上验证完成后,又手动敲了一遍到文档中......,所以代码中可能会有些错误(啥符号忘写之类的,总的代码程序应该是没有大问题的)。如果发现有错误,欢迎提出,我会及时修改,欢迎交流。

总之,这里就是借助Binder API实现了一个简单的服务,也没啥其他的内容。


图解Android中的binder机制 一个进程是不能直接直接操作另一个进程的,比如说读取另一个进程的数据,或者往另一个进程的内存空间写数据,进程之间的通信要通过内核进程才可以,因此这里就要使用到进程通信工具Binder了如下图:Binder driver通过/dev/binder /dev/binder 提供了 open, release release, poll poll, mmap mmap, flush flush, and ioctl等操作的接口api。这样进程A和进程B就可以通过内核进程进行通信了。 阅读详情

相关推荐

【Android】关于binder_calls_stats服务

Android中的Binder Call Stats(Binder调用统计)是一项用于监控和记录Android系统中Binder通信的统计信息的功能。要收集Binder Call Stats,开发人员可以使用Android系统提供的工具和API,例如使用adb shell命令进行监测,或者使用Trace类和Debug类提供的方法进行手动埋点和记录统计数据。Binder调用的进程和线程信息:记录Binder调用发生的进程和线程信息,有助于分析系统中不同组件之间的通信情况。

aaajj的专栏 1669

Android binder学习笔记5 - 获取服务

目录1. 前言 1. 前言 本文主要是binder系列文章的总结笔记,主要是理清binder的总体流程和总体架构,期间会对照Android R进行代码重读,也会按照自己的理解对内容进行调整,以加深对binder总体的理解。本文主要讲述 获取service的过程。 ...

HZero 200

Android Binder 进程间通信

Linux 中的系统内存可以分为两个不同的区域:内核空间和用户空间。内核空间是内核(即操作系统的核心)执行(即运行)并提供其服务的地方。内存由 RAM(随机存取存储器)单元组成,其内容可以以极高的速度访问(即读取和写入),但只能临时保留(即,在使用时或最多在电源保持开启时保留)。它的目的是保存当前正在使用的程序和数据,从而充当 CPU(中央处理器)和速度慢得多的存储之间的高速中介,后者通常由一个或多个硬盘驱动器 (HDD) 组成。用户空间是用户进程(即内核以外的所有内容)运行的内存位置的集合。

LiuYong_01的博客 1968

Android Binder 系统学习笔记(一)Binder系统的基本使用方法

1.什么是RPC(远程过程调用) Binder系统的目的是实现远程过程调用(RPC),即进程A去调用进程B的某个函数,它是在进程间通信(IPC)的基础上实现的。RPC的一个应用场景如下: A进程想去打开LED,它会去调用led_open,然后调用led_ctl,但是如果A进程并没有权限去打开驱动程序呢? 假设此时有一个进程B由权限去操作LED驱动程序,那么进程A可以通过如下方式来操...

adl30141的博客 283

Android中Binder在项目中的具体使用详解

在 Android 应用程序中使用 Binder 通常可以通过两种方式实现,一种是使用 AIDL(Android 接口定义语言)定义接口,并通过 Binder 服务实现接口的跨进程调用,另一种是通过 Messenger 实现基于消息的跨进程通信。Binder API:位于 Java 层,是 Android 应用程序和 Binder 驱动之间的接口,它提供了创建 Binder 服务和跨进程访问 Binder 服务的方法和实现。在服务端B程序进行登录后,跳转到客户端程序A,打印的。

路宇的博客 3260

Frida精准定位Shopee x-sap-ri动态签名生成函数

x-sap-ri是Shopee客户端生成的上下文感知型动态令牌,本质为基于设备标识、请求路径与毫秒级时间戳三元组的SHA256哈希值,经Base64编码后作为防重放与防批量伪造的核心校验字段。其生成逻辑深度混淆且跨Java/Native层,静态分析失效,而Frida凭借内存级函数调用拦截与JNI层穿透能力,成为唯一可行的技术路径。本文聚焦Frida在加固App中的实战适配——通过libcrypto.so API特征扫描反向定位被抹名的生成函数,实现对x-sap-ri输入参数(如16字节device_id加密

weixin_33978578的博客 610

Android系统篇之----Binder机制和远程服务调用机制分析

一、前景概要 最近要实现Android中免注册Activity就可以运行的问题,那么结果是搞定了,就是可以不用在AndroidManifest.xml中声明这个Activity即可运行,主要是通过骗取系统,偷龙转凤技术的,这个知识点后面会详细讲解的,因为在研究了这个问题过程中遇到了很多知识点,当然最重要也是最根本的就是Android中的Binder机制和远程服务调用机制,而关于Binder机

king16304的博客 246

速腾16线激光雷达(RS-16)在ubuntu18.04系统下跑SC-A-LOAM算法

说明: 简要记录一下速腾16线激光雷达即RS-16在ubuntu18.04系统下跑SC-A-LOAM算法的过程,因为SC-A-LOAM算法源码不支持RS雷达的数据,大致思想就是先将rs雷达发布的激光数据转换为velodyne类型的数据,考虑到接下来还要基于RS-16实时运行SC-A-LOAM算法,这里提前将RS_SDK驱动安装好。 1 搭建SC-A-LOAM算法运行环境 首先需要在电脑上搭建SC-A-LOAM算法的运行环境,见文章《ubuntu18.04搭建SC-A-LOAM环境并运行》 本文所使用的系统架

超爱吃小蛋糕的66的博客 2373

Android Binder (可以直接写在项目中的写法)

此篇为大家展示一个写在项目中的写法,native层的service注册和获取服务,加上回调。 首先展示一下项目目录 binder通信是基于aidl接口实现的,使用aidl接口可以省略许多不必要的代码。 工程的基础mk Android.mk include $(call all-subdir-makefiles) Android.bp subdirs = ["cmd","lib","service"] cmd文件夹代表服务从这个文件夹启动,当然如果特别完整的需要把 .rc文件和SELINUX权限.

转载和创作优秀的博客 1047

详解Numpy中的transpose方法

最近在学Numpy碰到了关于数组转置和换轴的概念,尤其是对tanspose方法有些疑惑,尤其是多维,查了不少资料,终于搞懂了。 Numpy数组的轴(axis) 所谓的**轴(axis)**可以理解为数组的维度。 具体而言,二维数组就是有两个维度,如果从空间上看,它就是一个平面,由x轴和y轴构成,而与此相对应的,该二维数组就有两个轴,x轴对应0轴,y轴对应1轴。 同理,三维数组有三个维度,空间上...

BlankGrid的博客 936

vLLM 多机多卡推理测试与验证(Kubernetes)vLLM 多机多卡推理 Kubernetes 验证

本文记录在两台 L20 机器,每台机器 4 块 L20 显卡(46G)的环境下,使用 vLLM 部署 Qwen2.5-32B-Instruct-GPTQ-Int4 模型并提供多节点多卡推理服务的过程。服务(Serving)模型服务是指将模型部署到生产环境中,通过 API 或其他接口提供预测服务的过程。【分布式推理与服务】(Distributed Inference and Serving)是指在多个机器或设备之间部署和管理机器学习模型,以高效地处理推理请求并满足大规模服务需求。3、启动 vLLM 服务。

流水_鱼鱼的博客 3459

音乐播放的简单实现——Service,SeekBar

转载请注明出处(万分感谢!): https://blog.youkuaiyun.com/weixin_40790006/article/details/79993530接口:package com.example.f405.musictest; /** * Created by F405 on 2018/4/18. */ public interface IMusicService { pu...

weixin_40790006的博客 807

SAP特殊采购类80实战:跨工厂生产配置避坑指南(附完整测试流程)

本文深入解析SAP特殊采购类80在跨工厂生产场景下的实战应用与配置要点。文章从核心业务逻辑出发,详细拆解了后台配置、主数据与BOM的“双工厂”思维模式,并提供了从创建需求到成品收货的完整测试流程。重点揭示了多层BOM下的需求传递陷阱及常见报错解决方案,旨在帮助SAP顾问及用户规避实施风险,实现资源的灵活调度与流程自动化。

wind6的博客 1139

messenger android 4.,AndroidIPC机制(4)-Messenger

一、概述除了使用 AIDL 进行 IPC 外,我们还可以使用 Messenger 来替代 AIDL。通过在 Message 对象中放入需要传递的对象,利用 Messenger 在不同进程间传递 Message 对象,就可以方便地进行进程间通信了Messenger 是一种轻量级的 IPC 方案,底层实现依然是 AIDL,通过 Messenger 的两个构造方法就可以看出来public Messeng...

weixin_39747807的博客 162

电动汽车整车控制器 UDS诊断功能开发调试优化方法

摘要:通过某电动汽车VCU开发过程中,UDS诊断功能的调试,发现一些测试中存在的问题,比如覆盖度不够、效率低下等,提出了相应的优化方法,并经过测试验证其可行性,此方法亦可推广应用至BMS、HCM等其他控制器的UDS诊断开发调试过程中。希望能给相关技术人员带来参考和帮助。

qq_43011586的博客 2142

yolov26改进 | 检测头篇 | 利用渐近特征金字塔网络AFPN改进yolov26检测头融合P2网络结构(让小目标无所遁形,全网独家首发)

本文介绍一种基于AFPN渐近特征金字塔网络改进的YOLOv26四检测头Detect_FPN。AFPN通过逐级融合底层细节、中层结构与高层语义特征,缩小不同尺度特征之间的语义差距,减少直接融合带来的信息冲突,使检测头获得更稳定、更充分的多尺度表达。本文进一步增加高分辨率小目标检测分支,强化对微小目标、密集目标和复杂背景目标的感知能力,适合工业缺陷、遥感及无人机等场景。文中将展示基础模型与改进模型的训练对比结果,并提供完整代码、配置文件、模块注册方法及Codex修改思路,方便直接复现和二次创新。

Snu77的博客 371

图解Android中的Binder机制

前言 Binder做为Android中核心机制,对于理解Android系统是必不可少的,关于binder的文章也有很多,但是每次看总感觉看的不是很懂,到底什么才是binder机制?为什么要使用binder机制?binder机制又是怎样运行的呢?这些问题只是了解binder机制是不够的,需要从Android的整体系统出发来分析,在我找了很多资料后,真正的弄懂了binder机制,相信看完这篇文章大家也...

有图有真相 2万+

Linux 下 OpenClaw 安装全记录:从零到一的保姆级图文教程

本文主要介绍了Linux 下 OpenClaw 安装全记录:从零到一的保姆级图文教程,希望能对学习使用OpenClaw 的同学们有所帮助。 文章目录 1. 背景 2. 实战教程 2.1 步骤一 安装Node.js 2.2 步骤二:安装git 2.3 步骤三:安装并配置OpenClaw 2.4 步骤四:配置OpenClaw 2.5 步骤五:配置模型 2.6 步骤六:对话 3. 后续使用步骤 4. 报错解决方案 5. OpenClaw的卸载

weixin_43178406的博客 10万+

Android Binder原理解析

系统就会为我们把对应的远程服务端唤醒,看源码知道是通过ServiceManager 去远程服务用ClassLoader反射的方式启动需要启动的service。这里把我们传过来的对象进行解析,并回调了Stub的抽象方法addBook,这个抽象方法就是我们再Service中重写的那个方法。//将一个IBinder对象转换成一个com.love.candy.aidl,这里就是我们平常用到的那个方法了。//这里会通过Binder的onTransact方法回调到我们Stub中。//这里的值和Proxy中的值对应。

2501_90471794的博客 1372

中国通信企业协会网络安全人员能力认证培训课件

中国通信企业协会网络安全人员能力认证培训的课件,面向基础、专业级

吉林【1省-9地级市-60区县】独立行政边界-可编辑mxd文件+标准shape文件+标准成图TIF

本数据集涵盖 吉林省 全域的多尺度行政区划信息,按照行政层级划分为 1个省级单元、9个地级市以及60个区县级行政单元。数据内容包含以下部分:1、【独立行政边界数据】按照省、地级市、区县三级行政层级分别建立独立的边界矢量数据文件(即shp文件),可实现分级加载与独立编辑。2、【可编辑 MXD 工程文件】基于 ArcGIS 平台构建,保存了分级符号化方案、标注样式、投影坐标系以及图层组织结构,便于用户直接在 GIS 软件中加载和修改。3、【标准化 Shapefile 矢量文件(SHP)】采用国际通用的 ESRI Shapefile 格式,属性表中包含行政区划代码、名称、上级单位等信息,满足空间分析、地图制图及数据叠加等应用需求。4、【标准成图 GeoTIFF 栅格文件(TIF)】按照制图规范输出的高分辨率 GeoTIFF 格式地图文件,保留地理参考信息,可直接用于出版、报告或网络地图展示。5、【资源应用】该数据集不仅具备完整、精确的省行政区划边界信息,还可与多种地理空间数据进行无缝集成,因而在多个领域都具有广泛的应用潜力。5.1-在区域统计分析方面,研究人员可利用该数据集结合人口普查数据、经济指标、社会统计信息等,对该省及其下属各级行政单元的经济社会发展状况进行定量分析,支持宏观决策与区域规划。5.2-在空间可视化领域,借助 GIS 软件(如 ArcGIS、QGIS),该数据集可作为底图框架,与专题数据(如气候分布、土地利用类型、交通网络等)叠加,实现高分辨率、可定制化的地图制作与成果展示。5.3-在地理建模方面,行政边界可作为区域划分的基本单元,用于水文模拟、气候模型、生态系统评估等空间计算过程,为模拟结果提供明确的空间约束条件。

Android Binder 详解

Binder 是 Android 系统中核心的跨进程通信(IPC)机制,同时也是一套完整的 “通信框架”—— 它不仅解决了进程间隔离的通信问题,还提供了安全校验、服务管理、易用性封装等能力,是 Android 组件(如 Activity、Service、ContentProvider)跨进程协作的基础。

weixin_42065195的博客 1606

C# winform部署yolov8-onnx印章检测源码

测试环境:vs2019netframework4.7.2onnxruntime1.16.3opencvsharp4.8.0博客地址:https://blog.youkuaiyun.com/FL1623863129/article/details/135400235

android binder机制,注册系统服务--服务端servicemanager binder驱动

3 服务端servicemanager binder驱动 前面分析过Servicemanager进程中的main方法步骤, 1,调用binder_open方法打开binder驱动。 2,调用binder_become_context_manager方法注册成为binder服务的大管家。 3,调用binder_loop方法进入无限循环, 处理binder驱动发来的请求。   其中bind

Jack的博客 1012

microgrid.zip_分布式微电网_分布式电源_微电网_微电网 仿真_电网运行模型

微电网仿真模型,可以完美运行,包含多个分布式电源

Android进程间通信之一:Binder机制学习

Binder机制学习Binder驱动Binder核心APILinux 使用两级保护机制:0 级供系统内核使用,3 级供用户程序使用。Linux 下的传统 IPC 通信原理Linux 下的传统 IPC 通信原理Binder通信过程ServiceManager进程启动MMAP Binder驱动 binder驱动在以misc设备进行注册,作为虚拟字符设备,没有直接操作硬件,只是对设备内存的处理。 主要是驱动设备的初始化(binder_init),打开 (binder_open),映射(binder_mmap)

北洋的博客 9036

【新手入门】Android基础知识(二):Binder进程间通信,理解Binder工作原理以及Binder实体、Binder引用、Binder代理概念

Android Binder机制是一种跨进程通信(IPC)解决方案,采用C/S架构实现进程间通信。核心组件包括:服务端(Server)提供功能服务并在ServiceManager注册;客户端(Client)通过ServiceManager获取服务引用;内核Binder驱动负责数据传输。通信过程涉及三个关键对象:服务端的Binder实体、客户端的Binder代理以及内核的Binder引用。服务调用时,客户端通过代理发起请求,请求经Binder驱动转发至服务端处理,结果再沿原路径返回。该机制实现了进程间透明的方

Chesnut. 1388

Android中的binder机制详解

Android中的binder机制详解

QG 4628

Android中的Binder

binder是Android平台的一种跨进程通信(IPC)机制,从应用层角度来说,binder是客户端和服务端进行通信的媒介。

qq_44016573的博客 3123

android binder

android native(C++)层的service 一般都会用到binder,通过binder的机制对外提供接口,如果我们需要实现一个native 层的service,那么要怎么做呢? 这个基本上是一个固定的套路,所以我们需要先了解一下android 提供的binder (框架?)的关系。XXXService就是要基于binder通信的类。     例如要实现一个Test

xiongtiancheng的博客 726
上一篇: Android -- IPC通信机制之一Binder简介
下一篇: Android -- Android设备的启动流程概述
第一序列丶
博客等级 码龄11年 249粉丝 77原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值