我们知道在Android上和网络的服务器通信手段有很多种, 通常我们的业务数据承载应用层协议(http等)或传输层协议上(tcp/udp)进行交互。 那么在传输层的Android上的技术接口无非就是socket,socket就是一套接口,可以使用网络,文件或内存来做为媒介进行通信,但是在android中都可以使用namespace来选择使用哪种方式进行通信。

我们都知道,其实在Linux中‘一切皆是文件’,包括socket。ipc socket进行通信的媒介有以下三种:

1.网络端口;

   通过本地环回的虚接口(loopback),使用127.0.0.1作为回环地址,来收发数据。

2.文件系统;

  通过文件来做为收发数据的中转,数据交换的媒介。

3. 内存映射;

  通过在内存中开辟一块空间来做为收发数据的中转,也是通过文件的API接口完成的。

以上三种方式都可以作为在android中的ipc socket进行通信,在android中的localsocket 支持以上的#2和#3,从执行效率上来看,#3的效率要更高。

在android中使用LocalSocket的事例就是应用程序APP进程的创建过程。

当我们使用Context#startActivity启动一个Activity时,是需要先创建APP进程,而APP进程的创建是通过android zygote进程来创建的,那么AMS进程需要和zygote进程进行通信,

通信的媒介就是基于LocalSocketAddress$Namespace#RESERVED(也就是会在/dev/socket目录下创建一个socket文件)。

与zygote进程建立连接的关键方法:Process#openZygoteSocketIfNeeded

private static final String ZYGOTE_SOCKET = "zygote";private static void openZygoteSocketIfNeeded()             throws ZygoteStartFailedEx {            ...            try {                sZygoteSocket = new LocalSocket();                 sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,   //                        LocalSocketAddress.Namespace.RESERVED));                ...                break;            } catch (IOException ex) {                ...            }    }
LocalSocket可以直接通过new关键字进行创建,调用LocalSocket#connect,需要传递LocalSSocketAddress对象,这个对象需要传递一个名称,这个名称和服务端约定好。

第二参数既是Namespace,是一个enum类型的。连接成功之后,就可以向使用普通的socket对象一样,获取inputstream和outputstream和服务器进行通信,交互数据。

public class LocalSocketAddress{    public enum Namespace {        /** A socket in the Linux abstract namespace */        ABSTRACT(0),        /**         * A socket in the Android reserved namespace in /dev/socket.         * Only the init process may create a socket here.         */        RESERVED(1),        /**         * A socket named with a normal filesystem path.         */        FILESYSTEM(2);    }}

zygote对应的服务端代码如下:

private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";/**     * Registers a server socket for zygote command connections     *     * @throws RuntimeException when open fails     */    private static void registerZygoteSocket() {        if (sServerSocket == null) {            int fileDesc;            try {                String env = System.getenv(ANDROID_SOCKET_ENV);                fileDesc = Integer.parseInt(env);            } catch (RuntimeException ex) {                throw new RuntimeException(                        ANDROID_SOCKET_ENV + " unset or invalid", ex);            }            try {                sServerSocket = new LocalServerSocket(                        createFileDescriptor(fileDesc));            } catch (IOException ex) {                throw new RuntimeException(                        "Error binding to local socket '" + fileDesc + "'", ex);            }        }    }static native FileDescriptor createFileDescriptor(int fd) throws IOException;

更多相关文章

  1. Android进程保活
  2. Android——进程通信/ AIDL/Message相关知识总结贴
  3. Android进程内存上限
  4. Android 实现蓝牙客户端与服务器端通信
  5. 浅谈Android中的线程的通信及Handle机制
  6. android蓝牙通信
  7. 理解Android进程创建流程(转)
  8. 从linux看Android之一--init进程

随机推荐

  1. 在回发之前在Jquery LinkBut​​ton中验
  2. Angular2-对象作为无线电输入值
  3. 如何在HTML视频标签中播放FLV视频?
  4. HTML5-Service Worker实现离线页面访问
  5. reload a div without reloading the who
  6. js获取html下拉框中选中值的自定义属性值
  7. html+css 图片右上角加删除叉,图片删除
  8. HTML DIV百分比宽度奇奇怪怪的间距产生了
  9. seo 优化去掉html 页面的后缀 .html
  10. form在提交时被取消:因为form没有被连接