Android Kotlin 使用Binder、管道、Socket、文件共享和信号量进行进程间通信的简单示例

大多情况下我们接触到的都是一些概念性的文章,希望这篇文章能带给大家不同的体验,让大家能够更好地消化进程间通信相关的知识。

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()
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiet_h

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值