说起 Android 进行间通信,大家第一时间会想到 AIDL,但是由于 Binder 机制的限制,AIDL 无法传输超大数据。
那么我们如何在进程间传输大数据呢?
Android 中给我们提供了另外一个机制: LocalSocket。它会在本地创建一个 socket 通道来进行数据传输。
那么它怎么使用?
首先我们需要两个应用: 客户端和服务端。
override fun run() {
server = LocalServerSocket("xxxx")
remoteSocket = server?.accept()
...
}
先创建一个 LocalServerSocket 服务,参数是服务名,注意这个服务名需要唯一,这是两端连接的依据。
然后调用 accept 函数进行等待客户端连接,这个函数是 block 线程的,所以例子中另起线程。
当客户端发起连接后,accept 就会返回 LocalSocket 对象,然后就可以进行传输数据了。
var localSocket = LocalSocket()
localSocket.connect(LocalSocketAddress("xxxx"))
两端的 socket 对象是一个类,所以两端的发送和接受代码逻辑一致。
通过 localSocket.inputStream 和 localSocket.outputStream 可以获取到输入输出流,通过对流的读写进行数据传输。
注意,读写流的时候一定要新开线程处理。
因为 socket 是双向的,所以两端都可以进行收发,即读写。
发送数据
var pool = Executors.newSingleThreadExecutor()
var runnable = Runnable {
try {
var out = xxxxSocket.outputStream
out.write(data) out.flush()
} catch (e: Throwable) {
Log.e("xxx", "xxx", e)
}
}
pool.execute(runnable)
localSocket.connect(LocalSocketAddress("xxx"))
var runnable = Runnable {
while (localSocket.isConnected) {
var input = localSocket.inputStreaminput.read(data)
...
}
}
Thread(runnable).start()
首先需要定义一套协议。
写数据
var pool = Executors.newSingleThreadExecutor()
var out = DataOutputStream(xxxSocket.outputStream)
var runnable = Runnable {
try {
out.writeInt(data.size) out.write(data) out.flush()
} catch (e: Throwable) {
Log.e("xxx", "xxx", e)
}
}
pool.execute(runnable)
读数据
var runnable = Runnable {
var input = DataInputStream(xxxSocket.inputStream)
var outArray = ByteArrayOutputStream()
while (true) {
outArray.reset()
var length = input.readInt()
if(length > 0) {
var buffer = ByteArray(length)
input.read(buffer)
...
}
}
}
Thread(runnable).start()
var buffer = ByteArray(1228800)
input.read(buffer)
写入
var pool = Executors.newSingleThreadExecutor()
var out = DataOutputStream(xxxSocket.outputStream)
var runnable = Runnable {
try {
out.writeInt(data.size)
var offset = 0
while ((offset + 1024) <= data.size) {
out.write(data, offset, 1024)
offset += 1024
}
out.write(data, offset, data.size - offset)
out.flush()
} catch (e: Throwable) {
Log.e("xxxx", "xxxx", e)
}
}
pool.execute(runnable)
读取
var input = DataInputStream(xxxSocket.inputStream)
var runnable = Runnable {
var outArray = ByteArrayOutputStream()
while (true) {
outArray.reset()
var length = input.readInt()
if(length > 0) {
var buffer = ByteArray(1024)
var total = 0
while (total + 1024 <= length) {
var count = input.read(buffer)
outArray.write(buffer, 0, count)
total += count
}
var buffer2 = ByteArray(length - total)
input.read(buffer2)
outArray.write(buffer2)
var result = outArray.toByteArray()
...
}
}
}
Thread(runnable).start()