✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。
🍎个人主页:Meteors.的博客
💞当前专栏:知识分享
✨特色专栏:知识分享
🥭本文内容:安卓进阶——跨进程通信
📚 ** ps **  :阅读文章如果有问题或者疑惑,欢迎在评论区提问或指出。


目录

一、 AIDL

(一)AIDL基础使用

1. 定义AIDL接口

2. 定义Parcelable数据类

3. 实现Service 

4. 客户端绑定服务

(二)AIDL高级特性

1. 异步回调接口

二、 Socket

(一)服务端实现

(二)客户端实现

三、 Binder

(一)介绍

(二)优势

(三)架构与核心组件

(四)使用

1. 定义 AIDL 接口文件

2. 实现服务端

3. 实现客户端

四、 Messenger

(一)介绍

(二)设计思想

(三)关键特点

(四)Messenger 的通信模型

1. 单向通信模型

2. 双向通信模型

(五)使用demo

1. 实现服务端

(1)创建 Service并定义用于处理消息的 Handler

(2)创建 Messenger,并重写 onBind()方法

(3)在 AndroidManifest.xml中注册 Service

2. 实现客户端

(1)绑定服务

(2)创建自己的 Handler和 Messenger来接收服务端的回复

(3)回调中创建服务端的 Messenger并发送消


一、 AIDL

(一)AIDL基础使用

AIDL(Android Interface Definition Language)让Binder通信更加简单规范。

1. 定义AIDL接口

// IUserManager.aidl
package com.example.ipc

interface IUserManager {
    void addUser(in User user)
    List<User> getUserList()
    int getUserCount()
}

// User.aidl
parcelable User

2. 定义Parcelable数据类

@Parcelize
data class User(
    val name: String,
    val age: Int
) : Parcelable

3. 实现Service 

class UserManagerService : Service() {
    private val userList = CopyOnWriteArrayList<User>()
    
    private val binder = object : IUserManager.Stub() {
        override fun addUser(user: User) {
            userList.add(user)
        }
        
        override fun getUserList(): MutableList<User> {
            return userList
        }
        
        override fun getUserCount(): Int {
            return userList.size
        }
    }
    
    override fun onBind(intent: Intent): IBinder {
        return binder
    }
}

4. 客户端绑定服务

class MainActivity : AppCompatActivity() {
    private var userManager: IUserManager? = null
    private var bound = false
    
    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            userManager = IUserManager.Stub.asInterface(service)
            bound = true
            
            // 使用服务
            userManager?.addUser(User("Alice", 30))
            val count = userManager?.userCount
            Log.d("IPC", "User count: $count")
        }
        
        override fun onServiceDisconnected(name: ComponentName?) {
            bound = false
            userManager = null
        }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bindService()
    }
    
    private fun bindService() {
        val intent = Intent(this, UserManagerService::class.java)
        bindService(intent, connection, Context.BIND_AUTO_CREATE)
    }
    
    override fun onDestroy() {
        super.onDestroy()
        if (bound) {
            unbindService(connection)
            bound = false
        }
    }
}

(二)AIDL高级特性

1. 异步回调接口

// IDataCallback.aidl
interface IDataCallback {
    void onSuccess(in String result)
    void onError(int errorCode)
}

// 在IUserManager.aidl中添加异步方法
interface IUserManager {
    void processDataAsync(String data, IDataCallback callback)
}

// 服务端实现
class UserManagerService : Service() {
    private val binder = object : IUserManager.Stub() {
        override fun processDataAsync(data: String, callback: IDataCallback) {
            // 在后台线程处理
            thread {
                try {
                    // 模拟耗时操作
                    Thread.sleep(1000)
                    val result = "Processed: $data"
                    callback.onSuccess(result)
                } catch (e: Exception) {
                    callback.onError(-1)
                }
            }
        }
    }
}

二、 Socket

(一)服务端实现

class SocketServerService : Service() {
    private var serverSocket: ServerSocket? = null
    private var isRunning = false
    private val clientHandlers = CopyOnWriteArrayList<ClientHandler>()
    
    inner class ClientHandler(private val socket: Socket) : Runnable {
        private val gson = Gson()
        
        override fun run() {
            try {
                val input = BufferedReader(InputStreamReader(socket.getInputStream()))
                val output = PrintWriter(socket.getOutputStream(), true)
                
                while (!socket.isClosed && isRunning) {
                    val message = input.readLine() ?: break
                    
                    // 处理JSON消息
                    val user = gson.fromJson(message, User::class.java)
                    user?.let {
                        // 处理用户数据
                        processUser(it)
                        
                        // 返回响应
                        val response = gson.toJson(mapOf("status" to "success", "user" to it))
                        output.println(response)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                socket.close()
                clientHandlers.remove(this)
            }
        }
        
        private fun processUser(user: User) {
            // 处理用户逻辑
        }
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        startServer()
        return START_STICKY
    }
    
    private fun startServer() {
        thread {
            try {
                serverSocket = ServerSocket(8888)
                isRunning = true
                
                while (isRunning) {
                    val client = serverSocket?.accept()
                    client?.let {
                        val handler = ClientHandler(it)
                        clientHandlers.add(handler)
                        thread { handler.run() }
                    }
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        isRunning = false
        serverSocket?.close()
        clientHandlers.forEach { it.socket.close() }
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
}

(二)客户端实现

class SocketClientActivity : AppCompatActivity() {
    private var socket: Socket? = null
    private var output: PrintWriter? = null
    private var input: BufferedReader? = null
    private val gson = Gson()
    
    private fun connectToServer() {
        thread {
            try {
                socket = Socket("localhost", 8888)
                output = PrintWriter(socket?.getOutputStream(), true)
                input = BufferedReader(InputStreamReader(socket?.getInputStream()))
                
                // 发送用户数据
                sendUser(User("Charlie", 28))
                
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    private fun sendUser(user: User) {
        thread {
            try {
                val json = gson.toJson(user)
                output?.println(json)
                
                // 读取响应
                val response = input?.readLine()
                Log.d("Socket", "Response: $response")
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}

三、 Binder

(一)介绍

Binder 是 Android 系统中用于跨进程通信的主要机制。所谓跨进程通信,就是让运行在不同进程中的组件(例如,一个 App 调用系统相机服务)能够进行数据交换和调用方法,连接这些孤立的进程的“桥梁”就是 Binder。

(二)优势

  • 高性能:相比传统的 Linux IPC(如管道、消息队列、Socket),Binder 只需要一次数据拷贝,效率非常高。这是因为它利用了内存映射技术。

  • 安全性:Binder 机制继承了 Android 的 UID/PID 标识,支持通信双方的身份验证,这是 Socket 等机制不具备的。系统服务可以验证调用者的权限。

  • 面向对象:Binder 使用起来很像本地方法调用,对开发者更友好。你可以定义一个接口,然后在客户端调用,服务端实现,感觉就像在调用本地对象的方法一样。

(三)架构与核心组件

所在进程

职责

Binder 驱动

Linux 内核

IPC 通信的核心。它不是一个硬件驱动,而是一个字符设备驱动(/dev/binder)。负责进程间通信的建立、数据交换、线程管理等所有底层工作。

服务端

服务进程

提供具体服务的进程。它会创建 Binder 对象并实现其业务逻辑。

Binder 实体对象

服务进程

服务端创建的、真正提供功能的对象。它有一个唯一的标识,称为 Binder 引用

代理对象

客户端进程

客户端持有的一个接口。它对客户端来说看起来就像本地对象,但当客户端调用其方法时,它会将调用信息打包并传递给 Binder 驱动。

客户端

客户端进程

需要调用服务的进程。它持有服务端的 代理对象

(四)使用

1. 定义 AIDL 接口文件

// IMyService.aidl
package com.example.service;

// 声明接口
interface IMyService {
    // 定义一些方法
    int add(int a, int b);
    String greet(String name);
}

2. 实现服务端

public class MyService extends Service {
    private final IMyService.Stub mBinder = new IMyService.Stub() {
        @Override
        public int add(int a, int b) {
            // 这里是在服务端进程中执行的!
            return a + b;
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

3. 实现客户端

// MainActivity.java
public class MainActivity extends Activity {
    private IMyService myService;
    private boolean isBound = false;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 关键步骤:将 IBinder 转换为 AIDL 接口
            myService = IMyService.Stub.asInterface(service);
            isBound = true;

            // 现在可以调用远程方法了!
            try {
                int result = myService.add(5, 3);
                String greeting = myService.greet("Android");
                Log.d("Client", "Result: " + result + ", Greeting: " + greeting);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            myService = null;
            isBound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent();
        intent.setAction("com.example.service.MY_SERVICE_ACTION");
        intent.setPackage("com.example.service"); // 设置包名用于精确匹配(Android 5.0+ 必须)
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isBound) {
            unbindService(connection);
            isBound = false;
        }
    }
}

四、 Messenger

(一)介绍

Messenger 是 Android 提供的一种基于 消息(Message)的跨进程通信方式。它的底层实现完全依赖于 Binder,但因为它封装了 AIDL 的复杂细节,提供了类似 Handler的简单 API,所以使用起来非常方便,特别适合不需要并发操作的场景。

(二)设计思想

核心思想:将一个进程的 Handler对象“传递”给另一个进程,让另一个进程可以向这个 Handler发送 Message对象,从而实现通信。

你可以把它想象成进程间的“信使”

  • 服务端创建一个 Handler来处理消息。

  • 然后基于这个 Handler创建一个 Messenger(信使)。

  • 客户端拿到这个 Messenger的引用后,就可以用它来向服务端的 Handler发送消息了。

(三)关键特点

优点简单易用,无需编写 AIDL 文件,自动处理了线程排队(串行处理)。

缺点功能单一,只能单向传递消息(Message对象)。如果要实现双向通信,需要建立两个 Messenger。不适合需要远程方法调用的复杂场景。

(四)Messenger 的通信模型

Messenger 通信通常是 一对一的,遵循典型的客户端-服务器模型。

1. 单向通信模型

  1. 服务端:创建一个 Handler来处理消息,并由此创建一个 Messenger。在 onBind()中返回这个 Messenger底层的 Binder对象。

  2. 客户端:绑定服务后,利用服务返回的 Binder对象创建一个 Messenger

  3. 客户端:使用 messenger.send(Message msg)方法向服务端发送消息。

  4. 服务端:在它的 Handler的 handleMessage()方法中接收到这条消息并进行处理。

2. 双向通信模型

  1. 在单向通信的基础上,客户端在发送消息时,需要将自己的一个 Messenger通过 Message.replyTo字段附带过去。

  2. 服务端在 handleMessage()中收到消息后,可以从消息中取出客户端的 Messenger

  3. 服务端现在也可以用这个 Messenger向客户端发送消息了。

  4. 客户端也需要一个自己的 Handler和 Messenger来接收并处理服务端回传的消息。

(五)使用demo

1. 实现服务端

(1)创建 Service并定义用于处理消息的 Handler

(2)创建 Messenger,并重写 onBind()方法

// MessengerService.java
public class MessengerService extends Service {

    // 用于处理从客户端发送来的消息的线程
    private static class IncomingHandler extends Handler {
        private final Application application;
        // 用于向客户端回复的 Messenger
        private Messenger clientMessenger;

        public IncomingHandler(Application application) {
            this.application = application;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // 定义消息类型,例如 MSG_FROM_CLIENT
                case 1001:
                    Log.i("Server", "Received from client: " + msg.getData().getString("data"));

                    // 获取客户端信使(用于回复)
                    clientMessenger = msg.replyTo;
                    if (clientMessenger != null) {
                        try {
                            // 准备回复给客户端的消息
                            Message replyMsg = Message.obtain(null, 1002);
                            Bundle bundle = new Bundle();
                            bundle.putString("data", "Hello Client, I‘m Server!");
                            replyMsg.setData(bundle);

                            // 向客户端发送回复
                            clientMessenger.send(replyMsg);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    // 服务端的信使,其内部关联了处理消息的 Handler
    private final Messenger mMessenger = new Messenger(new IncomingHandler(getApplication()));

    @Override
    public IBinder onBind(Intent intent) {
        // 将信使内部的 Binder 对象返回给客户端
        return mMessenger.getBinder();
    }
}

(3)在 AndroidManifest.xml中注册 Service

<service android:name=".MessengerService"
         android:enabled="true"
         android:exported="true">
    <intent-filter>
        <action android:name="com.example.app.MESSENGER_SERVICE" />
    </intent-filter>
</service>

2. 实现客户端

(1)绑定服务

(2)创建自己的 Handler和 Messenger来接收服务端的回复

(3)回调中创建服务端的 Messenger并发送消息

// MainActivity.java
public class MainActivity extends AppCompatActivity {

    private Messenger mServiceMessenger; // 指向服务端的信使
    private Messenger mClientMessenger;  // 指向客户端自身的信使(用于接收回复)
    private boolean isBound;

    // 客户端的 Handler,用于处理服务端发来的回复
    private static class ClientHandler extends Handler {
        private final WeakReference<MainActivity> mActivity;

        public ClientHandler(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = mActivity.get();
            if (activity != null) {
                switch (msg.what) {
                    // 定义消息类型,例如 MSG_FROM_SERVER
                    case 1002:
                        String reply = msg.getData().getString("data");
                        Log.i("Client", "Received reply from server: " + reply);
                        Toast.makeText(activity, "Server says: " + reply, Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 用服务端返回的 Binder 对象创建指向服务端的 Messenger
            mServiceMessenger = new Messenger(service);
            isBound = true;

            // 准备一条要发送给服务端的消息
            Message msg = Message.obtain(null, 1001); // 1001 是消息类型
            Bundle bundle = new Bundle();
            bundle.putString("data", "Hello Server, I‘m Client!");
            msg.setData(bundle);

            // !!! 关键步骤:将客户端的信使设置到消息的 replyTo 字段,以便服务端回复
            msg.replyTo = mClientMessenger;

            try {
                // 通过服务端信使发送消息
                mServiceMessenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceMessenger = null;
            isBound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 创建客户端自己的信使,用于接收回复
        mClientMessenger = new Messenger(new ClientHandler(this));

        // 绑定服务
        Intent intent = new Intent();
        intent.setAction("com.example.app.MESSENGER_SERVICE");
        intent.setPackage("com.example.app"); // 设置服务端包名(显式Intent)
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isBound) {
            unbindService(mConnection);
            isBound = false;
        }
    }
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐