跳到主要内容

Socket 通信

问题

在 Android 中 Socket 通信用于哪些场景?如何实现本地 Socket IPC?

答案

Socket vs Binder

特性BinderSocket
场景Android 进程间通信通用网络通信 / 本地 IPC
性能1 次拷贝2 次拷贝
安全内核验证身份需自行验证
跨网络
Android 使用系统 IPC 首选Zygote 通信、adb

本地 Socket 通信

Android 中 Zygote 进程使用 LocalSocket(Unix Domain Socket)接收 AMS 的 fork 请求:

// Server 端
class LocalSocketServer {
fun start() {
val server = LocalServerSocket("my_socket")

thread {
while (true) {
val client = server.accept()
handleClient(client)
}
}
}

private fun handleClient(client: LocalSocket) {
val input = BufferedReader(InputStreamReader(client.inputStream))
val output = PrintWriter(client.outputStream, true)

val message = input.readLine()
output.println("Server received: $message")

client.close()
}
}

// Client 端
class LocalSocketClient {
fun send(message: String): String {
val socket = LocalSocket()
socket.connect(LocalSocketAddress("my_socket"))

val output = PrintWriter(socket.outputStream, true)
val input = BufferedReader(InputStreamReader(socket.inputStream))

output.println(message)
val response = input.readLine()

socket.close()
return response
}
}

Android 中的 Socket 使用场景

  1. Zygote 通信:AMS 通过 LocalSocket 通知 Zygote fork 新进程
  2. adb 调试:adb 通过 TCP Socket 与设备通信
  3. 应用内 WebSocket:IM、实时推送
  4. 跨设备通信:局域网设备发现、数据传输
推荐方案

Android 进程间通信优先使用 Binder(AIDL/Messenger/ContentProvider)。Socket 适合跨网络通信或与非 Android 平台(如 Native 进程、PC)交互的场景。


常见面试问题

Q1: Zygote 为什么使用 Socket 而不是 Binder?

答案

Zygote 是所有应用进程的父进程,在 fork 子进程时需要保证单线程(fork 多线程进程会导致死锁等问题)。而 Binder 通信需要在进程中启动 Binder 线程池(多线程),与 fork 的安全要求冲突。Socket 是单线程通信模型,可以安全地在 fork 前后使用。

相关链接