前言:介绍一种使用socket通信的方法可以使native和framework自由通信

在Android系统中,java代码和本地代码(c/c++)直接的通信一般是使用jni接口,但是这种方法一般适用于framework层调用native层的代码,但本地代码层(native)又如何把消息传递给上层呢?我们可以借鉴Android中的GSP模块的实现方式来实现native到framework的消息传递,但是比较麻烦。所以我们在这里再介绍另一种方式: socket.

1 基础:

Android是基于linux的系统,系统底层机制基本上是相同的,因为分本地代码和java代码,并且是java代码通过jni调用本地代码执行,所以我们可以把本地代码的执行看成是服务器端的执行,framework端的代码看成是客户端代码。

Tcp通信基本流程:

  服务器端                                                                       客户端

  1.创建socket                                                             1.创建socket

  2.bind()

  3.listen()

  4.accecp()

  ----等待客户端连接----                                                2.connect()

  5.读数据(recv)                                                       3.写数据(send)

  6.写数据(send)                                                      4.读数据(recv)

  7.关闭socket(closesocket())                               5.关闭socket(closesocket())

ref:

http://www.cnblogs.com/bastard/archive/2012/10/09/2717052.html

2 实践:

2.1 Java层的主要代码:

LocalSocket so = null;
LocalSocketAddress addr;
so = new LocalSocket();
addr = new LocalSocketAddress(<span style="color:#cc33cc;">SOCKET_NAME</span>, LocalSocketAddress.Namespace.RESERVED);
so.connect(addr);

如果能正常connect到addr,那就可以像一般文件操作那样进行io读写了。

2.2 native层的主要代码:

cli_fd = android_get_control_socket(<span style="color:#993399;">SOCKET_NAME</span>);
retval = listen(cli_fd, backlog);
cli_fd_cmd = accept(cli_fd, (sockaddr *)&peeraddr, &socklen);

2.2.1 SOCKET_NAME的定义:

是android 一个字符串常量,在init.rc中定义,

2.2.2 增加socket资源

定义一个自己的服务,并命名为自己的SOCKET_NAME                                          [参照: 附录 android init language: 详细设置socket资源:]

即我们可以通过修改init.rc来改变socket

在android系统源代码目录树里面,有"android/system/core/rootdir/init.rc",

work01@ubuntu:~/hi3716cv200/system/core/rootdir$ ls
Android.mk  init.environ.rc.in  init.trace.rc  ueventd.rc
etc         init.rc             init.usb.rc

或者 android_install_folder/out/target/product/xxxx/root

详细: ref:

http://blog.csdn.net/yellow_hill/article/details/39548165

首先

添加一个服务(service),然后,在service下添加一个option 这里就是socket

取名为vdsocketservice_01的 servcie,同时加一个同名的类型为stream的socket,

service vdsocketservice_01 /system/bin/vdsocketservice_01socket vdsocketservice_01 stream 666oneshot

在启动vdsocketservice_01 服务时,就会为vdsocketservice_01 分配socket文件系统资源:dev/socket/vdsocketservice_01

vdsocketservice_01 服务的Socket资源和名称vdsocketservice_01 绑定起来。

这些都是在开机初始化化init进程中启动service时完成:

init进程会根据“socket”这个类型从而调用publish_socket(),

service_start        create_socket         publish_socket

2.2.3 构建编译框架:

我们可以参考android里面的例子,
在your_android_folder/hardware/ril/libril/ril.cpp
static int s_fdListen = -1;
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);if (s_fdListen < 0) {RLOGE("Failed to get socket '" SOCKET_NAME_RIL "'");exit(-1);}ret = listen(s_fdListen, 4);if (ret < 0) {RLOGE("Failed to listen on control socket '%d': %s",s_fdListen, strerror(errno));exit(-1);}
一个运用的例子如下:
android_get_control_socket 定义在如下文件
#include <cutils/sockets.h>
int main(const int argc, const char *argv[])
{//获取已绑定socketlsocket = android_get_control_socket(SOCKET_PATH);//监听socketlisten(lsocket, 5);for (;;) {//等待客户端建立连接s = accept(lsocket, &addr, &alen);for (;;) {//接收数据 相当于recvreadx(s, buf, count);//执行相关的操作execute(s, buf);}//关闭socketclose(s);}
}                

/system/bin/vdsocketservice_01就是我们自己的native服务器,在里面我们调用

  1. cli_fd = android_get_control_socket("server");
  2. retval = listen(cli_fd, backlog);
  3. cli_fd_cmd = accept(cli_fd, (sockaddr *)&peeraddr, &socklen);

这样就把服务器端建立起来了。

Java那边只需要使用普通socket API就可以和native服务器通信,但需要注意SOCKET_NAME的值必须和init.rc中的一致,我们这里的SOCKET_NAME为"server",如何编写init.rc请参考android/system/init/readme.txt.

ref:

http://blog.sina.com.cn/s/blog_82f2fc280101395m.html

附录:

1 android init language: 参照andorid的目录下自带的帮助文件 /system/core/init/readme.txt

Android Init Language
---------------------The Android Init Language consists of four broad classes of statements,
which are Actions, Commands, Services, and Options.
服务:
Services
--------
Services are programs which init launches and (optionally) restarts
when they exit.  Services take the form of:service <name> <pathname> [ <argument> ]*<option><option>...

socket 作为option的一种,这里看看帮助文件里面socket的举例:

socket <name> <type> <perm> [ <user> [ <group> ] ]Create a unix domain socket named /dev/socket/<name> and passits fd to the launched process.  <type> must be "dgram", "stream" or "seqpacket".User and group default to 0.
Example init.conf
on bootexport PATH /sbin:/system/sbin:/system/binexport LD_LIBRARY_PATH /system/libmkdir /devmkdir /procmkdir /sysmount tmpfs tmpfs /devmkdir /dev/pts<span style="background-color: rgb(51, 255, 51);"> mkdir /dev/socket</span>mount devpts devpts /dev/pts
....
service usbd /system/bin/usbd -ruser usbdgroup usbdsocket usbd 666

ref: 中文介绍

http://blog.csdn.net/yimiyangguang1314/article/details/6268177

2 socket stream的介绍:

Stream Supports reliable, two-way, connection-based byte streams without the duplication of data and without preservation of boundaries. ASocket of this type communicates with a single peer and requires a remote host connection before communication can begin. Stream uses the Transmission Control Protocol (Tcp) ProtocolType and the InterNetwork AddressFamily.

SOCK_STREAM提供面向连接的稳定数据传输,即TCP协议。SOCK_STREAM应用在C语言socket编程中,在进行网络连接前,需要用socket函数向系统申请一个通信端口。socket函数的使用方法如下

ref:

http://baike.baidu.com/view/4785427.htm

http://msdn.microsoft.com/en-us/library/system.net.sockets.sockettype(v=vs.110).aspx

3 ril 的源码和框架结构

http://en.pudn.com/downloads162/sourcecode/comm/modem/detail736165_en.html

ref:

http://calvinlee.github.io/blog/2012/04/26/android-init-socket/

本帖原创,请务必注明转载地址,谢谢!!!

Android localsocket 的基础和使用实践: 01相关推荐

  1. [编转]Android localsocket 的基础和使用实践: 02

    在上一节里,谈到了基础和具体是实践实现: 这一节涉及调试和具体的实践测试: 例子源码在: http://download.csdn.net/detail/goleftgoright/4183596 下 ...

  2. android系统核心机制 基础(01)智能指针wp sp

    该系列文章总纲链接:android 系统核心机制基础 系列文章目录 本章关键点总结 & 说明: 以上是本模块的导图,整体概括了智能指针的几个要点,引用计数,弱转强,flag标志意义以及Ligh ...

  3. XCoreRedux框架:Android UI组件化与Redux实践

    XCoreRedux框架:Android UI组件化与Redux实践 @author: 莫川 https://github.com/nuptboyzhb/ XCoreRedux源码+Demo:http ...

  4. 无线传感网课后习题(书本名称无线传感器网络基础 : 理论和实践 : Fundamentals of wireless sensor networks : theory and practice)

    无线传感网课后习题(书本名称无线传感器网络基础 : 理论和实践 : Fundamentals of wireless sensor networks : theory and practice) 1 ...

  5. Android网络编程基础(一) - 基础知识

    内容介绍:Android网络编程基础 博客地址:http://blog.csdn.net/kevindgk 版权声明:本文为原创文章,未经允许不得转载 联系方式:815852777@qq.com 前言 ...

  6. 神策(Android)- 集成基础埋点的整个过程

    记得最早以前都是用友盟全家桶,埋点是用友盟,推送也是用友盟:但是近俩年我参与开发的app,埋点都是用神策.推送都是用极光私服,分享都是去对应集成对应平台的SDK 神策篇 神策(Android)- 集成 ...

  7. android界面数据存储,Android应用开发基础之数据存储和界面展现(二)

    Android应用开发基础之数据存储和界面展现(二) 常见布局 相对布局 RelativeLayout 组件默认左对齐.顶部对齐 设置组件在指定组件的右边 android:layout_toRight ...

  8. 《大数据系统基础》课程实践项目中期答辩顺利举行,清华持续探索大数据人才教育创新之路

    2017年11月15日,清华大学大数据能力提升项目之<大数据系统基础>课程实践项目中期答辩在清华大学六号教学楼顺利举行.160余名同学分为21组,向任课老师和企业导师汇报了各组实践项目的进 ...

  9. Android中的基础控件TextView、Button、ImageView、EditText、ProgressBar

    文章目录 1 Android中的基础控件 1.1 控件的通用属性 2 TextView 2.1 TextView的继承关系 2.2 TextView的常用属性 3 EditText 3.1 常用属性 ...

最新文章

  1. Tomcat init 脚本并添加服务自启动
  2. C++书籍笔记目录汇总【目前1本读书笔记(持续更新中……)】
  3. java 中数组与list_Java中List与数组相互转换实例分析
  4. IP头、TCP头、UDP头详解以及定义
  5. matlab信号频率分析实验报告,信号抽样实验报告
  6. Php如何过360拦截,PHP常见漏洞修复文件-360漏洞修复插件
  7. 【1】Docker概述
  8. c++11 future promise
  9. .NET Core RSA 签名和验签(密钥为 16 进制编码)
  10. php ip重复注册,php中表单的重复提交怎么通过记录IP来防止
  11. js $.inArray
  12. oem13c安装参考
  13. os系统 测试网络软件,iStumbler For Mac v103.43 WiFi 信号强度检测工具 _ 黑苹果乐园...
  14. 2020.11.23Junit详解
  15. 【BX学习之打印机】 惠普5055(无线WiFi小型打印机双面复印扫描一体机)
  16. DP/最短路 URAL 1741 Communication Fiend
  17. 基于达索系统3DE平台实现企业数字化转型的场景应用
  18. 小小突击队服务器维护多久,《小小突击队》08月06日更新公告
  19. 杭电acm a+b问题
  20. 免费idc公益接口_数据科学促进社会公益免费开放数据的最佳来源

热门文章

  1. 通过Android反编译技术研究国内陌生人社交即时通讯的技术方案
  2. vue data变量之间相互赋值或进行数据联动
  3. Windows11 安装Docker,安装至D盘(其他非C盘皆可)
  4. MySQL报错 Packet for query is too large,server向mysql发送的数据包大小超过mysql限制
  5. C#LeetCode刷题之#136-只出现一次的数字(Single Number)
  6. 漏洞learning[安全大事记]
  7. 为什么我切换到React Native来创建超级简单的底页
  8. 手语识别_如何使用转移学习进行手语识别
  9. 如何创建多个条形图_学习使用D3创建条形图-初学者教程
  10. ubunut安装redis