在android root环境下,有一个后台服务server进程需要提供接口给控制台应用client调用,本来想用socket方式来做的,后台发现android有更高效的方式来实现.那就是binder.

查了一下资料,具体的binder驱动的实现细节比较复杂,网上一堆教程都是先aidl,再生成代码,

其实不用那么复杂,下面应该是最简单写法了。

server

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/Errors.h>
#include <pthread> using namespace android;
//客户端回调引用
sp<IBinder> clientCallback; enum {
code_test_hello = 1,
code_test_callback_registe = 2
} enum {
cb_code_test = 1
} void callback_test(const char* params) {
if (clientCallback == NULL) { \
LOGD("%s clientCallback == null", __FUNCTION__);
return;
}
if (!clientCallback->isBinderAlive()){
LOGD("%s clientCallback not alive", __FUNCTION__);
return;
} int32_t t = clientCallback->pingBinder();
bool b = clientCallback->isBinderAlive();
Parcel request, reply;
request.writeCString(params);
clientCallback->transact(EnumCallback::cb_code_test, request, &reply);
} class ServiceService: public BBinder {
public:
ServiceService();
virtual status_t onTransact(uint32_t code, const Parcel&, Parcel*, uint32_t){
switch(code) { case code_test_hello:
{
printf("from client:%s", request.readCString());
reply->writeCString("hello client");
return NO_ERROR;
}
case code_test_callback_registe:
{
clientCallback = request.readStrongBinder();
reply->writeInt32(0);
return NO_ERROR;
}
} return BBinder::onTransact(code, request, reply, flag);
}
}; void *binderThread (void *arg){
sp<ProcessState> proc(ProcessState::self());
defaultServiceManager()->addService(String16("ServiceService"), new ServiceService());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return ((void *)0);
} int initBinderPool() {
return pthread_create(NULL, NULL, binderThread, NULL);
} int main(int argc, char *argv[]) {
//启动binder框架线程池
initBinderPool();
while(true) {
callback_test("hello word");
sleep(1);
} return 0;
}

client

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <utils/Errors.h>
#include <stdio.h>
#include <binder/IMemory.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
#include <android/log.h> #define TAG "bindertest"
#define LOGD(...) \
printf(__VA_ARGS__); \
__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) using namespace android;
static sp<IBinder> service; enum {
code_test_hello = 1,
code_test_callback_registe = 2
} enum {
cb_code_test = 1
} class Callback : public BBinder {
public:
status_t onTransact(uint32_t code, const Parcel &request, Parcel *reply, uint32_t flag) {
switch (code) {
case cb_code_test:{
const char* str = request.readCString();
LOGD("msg from server cb:%s\n", str);
reply->writeInt32(0);
break;
}
} return BBinder::onTransact(code, request, reply, flag);
}
}; static void callback_connect(const sp<Callback>& callback) {
if (service == NULL) {
LOGD("[%s] service not init", __FUNCTION__);
return ret;
} Parcel request, reply;
request.writeStrongBinder(callback);
service->transact(CMD_CALLBACK_INIT, request, &reply);
} void* binderThread(void* params){
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return NULL;
} void testHello() {
if (service == NULL) {
LOGD("[%s] service not init", __FUNCTION__);
return ret;
} Parcel request, reply;
request.writeCString("hello server");
service->transact(code_test_hello, request, &reply);
printf("from server:%s", reply.readCString());
} int main(int argc, char *argv[]) {
sp<ProcessState> proc(ProcessState::self());
service = defaultServiceManager()->getService(String16("ServiceService"));
if (!service) {
LOGD("get ServiceService fail");
return 0;
} //注册回调
sp<Callback> callback = new Callback();
callback_connect(callback);
//启动binder线程池,不启动的话,server端的回调会卡住
pthread_create(NULL, NULL, binderThread,NULL); while(true) {
testHello();
sleep(1);
} return 0;
}

参考

http://qiushao.net/2019/12/29/Android%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91%E5%85%A5%E9%97%A8/9-%E6%B7%BB%E5%8A%A0native%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1/

android控制台应用binder通讯的更多相关文章

  1. android灭屏后调用binder通讯竟然影响了socket的POLL_OUT事件,怪事。

    当你的android在灭屏(休眠)时分派(dispatch) Ice调用过程中,如果创建了新的进程,你的响应将不会预期那样工作,尽管你已经调用 ice_response或 ice_exception, ...

  2. Android中的Binder机制的简要理解

    转载自:http://www.linuxidc.com/Linux/2012-07/66195.htm http://blog.csdn.net/sunxingzhesunjinbiao/articl ...

  3. Android深入浅出之Binder机制(转)

    Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的.所以搞明白B ...

  4. 岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯

    岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯 看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未尝不是一个适 ...

  5. 基于Android 平台简易即时通讯的研究与设计[转]

    摘要:论文简单介绍Android 平台的特性,主要阐述了基于Android 平台简易即时通讯(IM)的作用和功能以及实现方法.(复杂的通讯如引入视频音频等可以考虑AnyChat SDK~)关键词:An ...

  6. Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...

  7. 3Q大战现高潮,360 推出Android "3Q" IM即时通讯,岁末年初3Q大战惊现高潮

    岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯       看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未 ...

  8. 从AIDL开始谈Android进程间Binder通信机制

    转自: http://tech.cnnetsec.com/585.html 本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 ...

  9. [Android进阶]Binder学习(初始篇)

    Android中Binder学习(初始篇) 本篇博客学习自侯亮的博客.地址为: 红茶一杯话Binder 1 什么是Binder? 简单地说.Binder是Android平台上的一种跨进程交互技术. 该 ...

  10. 手把手教Android商业项目-即时通讯-i美聊

    [课程概况] 手把手教你从无到有的完整实现一个Android商业项目,是目前整个市场上所没有的课程,废话不多说,请往下看. [项目概况] 项目名称:i美聊 所属领域:移动社交 即时通讯   代码行数: ...

随机推荐

  1. Quartz.Net 主要概念介绍和吐槽

    我们经常遇到需要定时执行某些任务的情况,比如清理缓存.异步结果轮询等,如果不打算造轮子,那么选择一款合适的定时任务组件就很关键了.所幸,.Net 世界中的选项并不多:) 选型 主要有以下四款: Qua ...

  2. Naughty Stone Piles

    题目:http://codeforces.com/problemset/problem/227/D 题意:n堆个数石子,每堆石子有ai个,通过合并(即将一堆石子移到另一堆石子上),将所有石子合并为一堆 ...

  3. 微信小程序之permission字段

    最近查看我发布的小程序出了问题,没有显示天气,打开文件查看,出现如下提示 那么如何解决呢 在 app.json 里面增加 permission 属性配置然后在app.json中添加代码 整个app.j ...

  4. Android:LitePal 在第一次创建表之后第二次创建新的表不生效

    因为业务需求的增长,后续需要继续创建新的表,有可能代码没有任何报错,同时数据库也没有任何新的表加入进来. 修改 litepal.xml 的 version,如果之前是 1,那么修改为 2,总之比之前 ...

  5. Cesium渲染模块之Buffer

    1. 引言 Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业 ...

  6. WGCMS 奇迹网站系统 介绍[V2023.2.2]

    智鹏网站系统,请勿用作非法用途 权利和义务: 程序仅限学习技术使用,未经官方许可不得用于商业! 程序售价500元一套,绑定域名,不限制端口.如绑定:xx.com,则www.xx.com.mu.xx.c ...

  7. ESXi 安装 Truenas Core 解决企业共享存储免费方案

    服务器配置 创建虚拟机内存最少8+,建议选择32,CPU没啥用,我给了2,硬盘我选择了50G+8T,因为一个虚拟机无法使用两个存储池,所以全部使用非SSD硬盘,自带网卡删除,单独给一个直通网卡,建议上 ...

  8. linux 替换csv的换行符(Linux 替换^M字符 方法)

    sed -i 's/^M//g' a.csv 注意:这里的"^M"要使用"CTRL-V CTRL-M"生成,而不是直接键入"^M". 实验: ...

  9. python 多进程和异步io的有机结合 Error in atexit._run_exitfuncs

    众所周知,python的多线程开发在GIL(全局器解释锁)下饱受诟病,在单核模式下搞多线程对效率的提升相当有限.于是大家的共识就是搞io密集的程序,建议采用多线程,计算密集型的程序就搞多进程.近期的一 ...

  10. golang 切片(slice)

    1.切片的定义 切片(slice)是对数组一个连续片段的引用,所以切片是一个引用类型. 切片的使用与数组类似,遍历,访问切片元素等都一样.切片是长度是可以变化的,因此切片可以看做是一个动态数组. 一个 ...