大多情况下我们接触到的都是一些概念性的文章,希望这篇文章能带给大家不同的体验,让大家能够更好地消化进程间通信相关的知识。
tips: 在实际开发中,如果需要进行进程间通信,推荐使用 Binder、Broadcast、ContentProvider 等,这些机制更高效更安全。
1. Binder
使用AIDL
参考:https://blog.csdn.net/qq_42751010/article/details/132182022
2. 管道
服务端代码:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedWriter
import java.io.OutputStreamWriter
import java.io.PipedInputStream
import java.io.PipedOutputStream
class ServerMainActivity : AppCompatActivity() {
private lateinit var outputStream: PipedOutputStream
private lateinit var inputStream: PipedInputStream
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
outputStream = PipedOutputStream()
inputStream = PipedInputStream(outputStream)
lifecycleScope.launch(Dispatchers.IO) {
startServer()
}
}
private suspend fun startServer() {
val writer = BufferedWriter(OutputStreamWriter(outputStream))
while (true) {
// 从管道读取请求内容
val request = withContext(Dispatchers.IO) {
readRequestFromPipe()
}
val response = if (request == "open_camera") {
openCamera()
"Camera opened"
} else {
"Invalid request"
}
// 写入响应内容到管道
withContext(Dispatchers.IO) {
writer.write(response)
writer.newLine()
writer.flush()
}
}
}
private suspend fun readRequestFromPipe(): String {
val reader = BufferedReader(InputStreamReader(inputStream))
return withContext(Dispatchers.IO) {
reader.readLine()
}
}
private fun openCamera() {
// 打开摄像头的操作
}
}
客户端代码:
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PipedInputStream
import java.io.PipedOutputStream
class ClientMainActivity : AppCompatActivity() {
private lateinit var connectButton: Button
private lateinit var outputStream: PipedOutputStream
private lateinit var inputStream: PipedInputStream
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
connectButton = findViewById(R.id.connectButton)
connectButton.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
sendRequestToServer()
}
}
outputStream = PipedOutputStream()
inputStream = PipedInputStream(outputStream)
}
private suspend fun sendRequestToServer() {
try {
// 向管道写入请求内容
outputStream.write("open_camera".toByteArray())
// 等待服务端响应
val response = withContext(Dispatchers.IO) {
readResponseFromPipe()
}
Log.d("ClientMainActivity", "Received response: $response")
} catch (e: Exception) {
e.printStackTrace()
}
}
private suspend fun readResponseFromPipe(): String {
val reader = BufferedReader(InputStreamReader(inputStream))
return withContext(Dispatchers.IO) {
reader.readLine()
}
}
}
3. Socket
服务端代码:
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.ServerSocket
class ServerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_server)
// 启动协程执行服务端Socket通信
lifecycleScope.launch {
startServer()
}
}
private suspend fun startServer() {
val serverSocket = ServerSocket(8080) // 创建ServerSocket对象,监听指定端口
while (true) {
val clientSocket = serverSocket.accept() // 等待客户端连接
// 处理客户端请求
launch(Dispatchers.IO) {
val reader = BufferedReader(InputStreamReader(clientSocket.getInputStream()))
val writer = PrintWriter(clientSocket.getOutputStream(), true)
val request = reader.readLine() // 读取客户端发送的请求
Log.d("ServerActivity", "Received request: $request")
// 处理请求,并返回响应
val response = "Hello, client!"
writer.println(response)
Log.d("ServerActivity", "Sent response: $response")
if (request == "open_camera") {
// 在收到打开摄像头的请求后调用服务端打开摄像头的代码
openCamera()
}
writer.close()
reader.close()
clientSocket.close()
}
}
}
private fun openCamera() {
Log.d("ServerActivity", "Opening camera...")
// ...
}
}
客户端代码:
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.Socket
class ClientActivity : AppCompatActivity() {
private lateinit var connectButton: Button
private var clientSocket: Socket? = null
private var writer: PrintWriter? = null
private var reader: BufferedReader? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_client)
connectButton = findViewById(R.id.connectButton)
connectButton.setOnClickListener {
// 发送请求给服务端
lifecycleScope.launch(Dispatchers.IO) {
sendRequestToServer("open_camera")
}
}
// 在创建时连接到服务端
lifecycleScope.launch(Dispatchers.IO) {
connectToServer()
}
}
private suspend fun connectToServer() {
val serverAddress = "localhost" // 服务端地址
val serverPort = 8080 // 服务端端口
clientSocket = Socket(serverAddress, serverPort) // 创建Socket连接服务端
reader = BufferedReader(InputStreamReader(clientSocket?.getInputStream()))
writer = PrintWriter(clientSocket?.getOutputStream(), true)
Log.d("ClientActivity", "Connected to server")
}
private suspend fun sendRequestToServer(request: String) {
writer?.println(request) // 发送请求至服务端
Log.d("ClientActivity", "Sent request: $request")
val response = reader?.readLine() // 读取服务端的响应
Log.d("ClientActivity", "Received response: $response")
}
override fun onDestroy() {
super.onDestroy()
try {
// 关闭连接和资源
writer?.close()
reader?.close()
clientSocket?.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
4. 文件共享和信号量
服务端代码:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.concurrent.Semaphore
class ServerMainActivity : AppCompatActivity() {
private lateinit var requestFile: File
private lateinit var responseFile: File
private lateinit var semaphore: Semaphore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
requestFile = File(filesDir, "camera_request.txt")
responseFile = File(filesDir, "camera_response.txt")
semaphore = Semaphore(0)
lifecycleScope.launch(Dispatchers.IO) {
startServer()
}
}
private suspend fun startServer() {
while (true) {
// 等待信号量,表示有新的请求
semaphore.acquire()
if (requestFile.exists()) {
// 读取请求文件
val request = withContext(Dispatchers.IO) {
requestFile.readText()
}
val response = if (request == "open_camera") {
openCamera()
"Camera opened"
} else {
"Invalid request"
}
// 写入响应文件
withContext(Dispatchers.IO) {
responseFile.writeText(response)
}
// 释放信号量,通知客户端有响应可读取
semaphore.release()
}
}
}
private fun openCamera() {
// 打开摄像头的操作
}
}
客户端代码:
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.concurrent.Semaphore
class ClientMainActivity : AppCompatActivity() {
private lateinit var connectButton: Button
private lateinit var requestFile: File
private lateinit var responseFile: File
private lateinit var semaphore: Semaphore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
connectButton = findViewById(R.id.connectButton)
connectButton.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
sendRequestToServer()
}
}
requestFile = File(filesDir, "camera_request.txt")
responseFile = File(filesDir, "camera_response.txt")
semaphore = Semaphore(0)
}
private suspend fun sendRequestToServer() {
try {
// 创建请求文件并写入请求内容
requestFile.writeText("open_camera")
// 释放信号量,通知服务端有新的请求
semaphore.release()
// 等待服务端响应
semaphore.acquire()
val response = withContext(Dispatchers.IO) {
responseFile.readText()
}
Log.d("ClientMainActivity", "Received response: $response")
} catch (e: Exception) {
e.printStackTrace()
}
}
}