我们知道在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(安卓)渗透测试学习手册 第四章 对 Android(安卓)设备进
  2. Android的多任务之路
  3. 单线程模型中Message、Handler、Message Queue、Looper之间的关
  4. Android线程模型解析(包括UI的更新)
  5. Android(安卓)性能优化 内存优化 How Android(安卓)Managers Mem
  6. 有关Android线程的学习
  7. Android进程保活
  8. android adb端口被占用解决方案
  9. Android(安卓)M PackageManagerService解析

随机推荐

  1. Android(安卓)app:开机自动启动app demo
  2. android 在调用执行了reboot系统层做部分
  3. Android事件传递机制
  4. TextView过长显示省略号, TextView文字中
  5. Android中屏幕密度和图片大小的关系分析
  6. android 透明效果
  7. android中gps的使用以及解析nmea0183协议
  8. Android(安卓)相机拓展库,能够实时采集并
  9. Android布局优化
  10. Android(安卓)Screen Monitor使用