本人目前参与的一个项目,其Android系统是高度本地化定制的,APP上的数据主要来自本机硬件,这就需要一种机制来实现底层数据与上层APP之间进行交互。最初的想法使用JNI方式封装一个C程序库供APP调用,此种方式的好处就是APP程序相对简单,但坏处很明显:程序之间的耦合很大,未来维护与扩充比较困难,而且APP会显得庞大,运行效率不高。
既然JNI方式坏处这么明显,只能另想办法,比较常用的是采用中间件方式。基本架构就是增加一个中间件,用C实现,运行时为Linux下的一个单独进程,作为APP与底层各硬件模块之间的信使,用来传输与解析(封装)信息。
确定采用中间件方式后,首先要解决进程间通信问题。如果在应用层,APP与APP之间有多种进程间通信方式,主要是Ibinder,还有其它简单易用的,比如Intent、Broadcast、ContentProvider等,但我们要实现的是APP层与底层C进程的通信,所以不能采用应用层这些方式,首先能想到的就是采用Socket方式,虽然Socket主要是网络通信用的,但是在本机内实现进程间通信也是可以的。
现在思路很明显了,采用本机的Socket方式来实现进程间通信,我们知道Socket分为TCP与UDP,既然是本机,当然采用效率高的UDP方式。方案定下来后,就开始写demo进行验证此种方式的可行性与可靠性了。APP作为客户端,中间件作为服务器端,经过测试,发现两台机器之间,APP与中间件能通信,但是在本机内不能通信。测试时将APP装在Android模拟器上,如果中间件也运行于Android模拟器中,则不能通信,如果中间件运行于其它机器上则能进行通信。经过测试发现此种方式不可行(具体原因尚不知,希望有人能指导一下),所以采用Socket UDP方式也被排除。
最后经过研究,Android已经给出了方案,就是LocalSocket方式,此处方式不同于一般的Socket,没有TCP与UDP之分,是专门提供应用程序与Linux层通信的方式,里面封装了Socket的相关接口,使用起来也类似于Socket方式。
最后经过几次测试,终于实现了应用层与Linux层的通信,APP作为客户端,中间件作为服务器端,中间件能接收来自多个APP端的消息。
一、客户端关键代码:
1.生成LocalSocketAddress对象,传入服务名
public static final String SERVICE_NAME = "LocalSocketName";
LocalSocketAddress address = new LocalSocketAddress(SERVICE_NAME,Namespace.RESERVED);
注意:因为C程序会作为一个Socket服务随系统启动,此服务有一个服务名,所以要正确连接到服务器端,SERVICE_NAME两边要一致,同时第二个参数一定要为Namespace.RESERVED,否则连接不成功(注意:APP层也可以实现LocalSocket服务器端,主要可以用来测试客户端,如果用APP实现服务器端,测试连接时,第二个参数省略)。
2.使用LocalSocket对象主动连接服务器端
LocalSocket clientSocket = new LocalSocket();
clientSocket.connect(address);
注意:如果产生异常,比如服务不存在或LocalSocketAddress的参数不对,则连接不成功。
3.通过OutputStream发送数据
public static final String CHAR_SET = "GBK"; //字符编码格式
String sendStr = "发送给服务器端";
OutputStream outputStream = clientSocket.getOutputStream();
PrintWriter os = new PrintWriter(new OutputStreamWriter(outputStream,CHAR_SET), false);
os.print(sendStr);
if ( os.checkError() ) {
return false; //发送不成功
}
return true; //发送成功
注意:为了使中文不为乱码,应该采用GBK编码;本代码不能在UI线程中
4.通过InputStream接收来自服务器的数据
char[] dataBuf = new char[1024]; //接收数据缓存
InputStream inputStream = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(inputStream,CHAR_SET);
int count = isr.read(dataBuf);
if (count > 0) {
System.out.println(“接收来自服务器:”+new String(dataBuf,0,count));
}
注意:为了使中文不为乱码,应该采用GBK编码;本代码不能在UI线程中
二、服务器端配置:
1.在init.rc加入LocalSocket服务
service myLocalService /system/bin/LocalSocketName
socket LocalSocketName stream 666 system system
oneshot
三、服务器端关键代码:
1.监听来自客户端的连接
#define SOCKET_NAME "LocalSocketName"
...
int fdSockt = -1;
int fd = -1;
fdSockt = android_get_control_socket(SOCKET_NAME);
if (fdSockt >= 0) {
int ret = listen(fdListen, 10);
if ( ret >=0 ) {
struct sockaddr_un addr;
socklen_t socketlen = sizeof (addr);
fd = accept(fdSockt, (struct sockaddr *) &addr, &socketlen);
}
}
2.接收来自客户端的消息
int bytenumber ;
char receiveBuff[1024];
memset(receiveBuff, 0, 1024);
if ( fd >=0 ) {
if((bytenumber = recv(fd,receiveBuff,sizeof(receiveBuff),0))>0){
printf("接收消息:%s\n",receiveBuff);
}
}
3.给客户端返回消息
char sendBuff[1024] = "发送给客户端";
if (fd >=0) {
if(send(fd,sendBuff,strlen(sendBuff),0)> 0) {
printf("发送消息:%s\n",sendBuff);
}
}
四、将配置与服务器端源码编译进系统
由于LocalSocket服务需要编译进源码里才能启动,故需要加入到Android源码后编译并刷机,重启系统才能顺利运行。
分享到:
相关推荐
Android为用户与移动应用程序交互提供了全新的方式,同时也提供了实现这些交互的底层技术保障。而Android最令人心动之处,莫过于你可以为它编写软件,本书恰好可以为你提供这方面的帮助。 本书读者对象 阅读...
Android 是一个真正意义上的开源智能手机操作系统,该系统由底层的Linux、中间层的软件包和上层的Java应用程序组合而成。该系统一经推出立即受到了全球移动设备厂商和开发者的热捧。 2008年9月22日,美国运营商...
第一篇Android的前世今生——Android概述篇 第1章Android的前世今生 1.1 Android的起源 1.2开放手机联盟 1.3开源与相关协议 1.4系统的升级与发展 第2章Android体系结构 2.1四层空间基本结构 2.1.1 Android系统底层...
在内容上,《Android系统源代码情景分析(含CD光盘1张)》结合使用情景,全面、深入、细致地分析了Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层...
随着移动通信技术和网络技术的迅速发展,手机系统发生了巨大 的变化,从进行简单通话功能的非智能手机到现在集上网、聊天、收 发邮件、视频电话会议等各种服务与娱乐为一身的智能手机系统。由 Google公司牵头众多...
摘要:本文通过对Android RIL层代码分析,将android RIL层功能在纯LINUX平台上实现,完全脱离了Android系统.为基于LINUX的通用平台实现一套成熟的RIL层代码,并开发出相应的框架层,以便基于LINUX的平台能快速成熟的...
第一部分课程从最基础的Android应用开发环境搭建开始,简单讲解了Android界面及事件处理之后,深入剖析Android Handler多线程机制,重点讲解Android NDK应用层与驱动的通信; 第二部分内容,先简单讲解Android系统...
本文介绍了智能电视操作系统和其人机交互的发展现状,针对现有操作系统和交互方式提出了以Android OS和触摸板为核心的系统解决方案,介绍了软硬件平台的搭建过程,将整个系统分为硬件层、数据接入层、驱动层、框架层、...
以Android APP为移动端,构建实时监控环境的应用层,通过MQTT协议和TCP协议与网关进行数据交互; 以MySQL数据库服务器作为数据存储的空间。 上行数据:底层->网关->Android端(主线程中运行) 下行数据:Android->...
1.2 Android应用程序参考书籍 1.3 下载、编译和运行Android源代码 1.3.1 下载Android源代码 1.3.2 编译Android源代码 1.3.3 运行Android模拟器 1.4 下载、编译和运行Android内核源代码 1.4.1 下载...
在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...
• 应用程序框架 支持组件的重用与替换 • Dalvik Dalvik Dalvik Dalvik 虚拟机 专为移动设备优化 • 集成的浏览器 基于开源的 WebKit 引擎 • 优化的图形库 包括定制的 2D 图形库, 3D 图形库基于 OpenGL ES 1.0 ...
在内容上,本书结合使用情景,全面、深入、细致地分析了Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application...
在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...
在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...
在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...
在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...
Android应用程序框架篇从组件、进程、消息以及安装四个维度来对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上去掌握每一个层次...
1.2 Android应用程序参考书籍 1.3 下载、编译和运行Android源代码 1.3.1 下载Android源代码 1.3.2 编译Android源代码 1.3.3 运行Android模拟器 1.4 下载、编译和运行Android内核源代码 1.4.1 下载Android内核...
Android应用程序框架篇从组件、进程、消息以及安装四个维度来对Android应用程序的框架进行了深入的剖析。 通过上述内容及其组织,本书能使读者既能从整体上把握Android系统的层次结构,又能从细节上去掌握每一个层次...