Android进程之间的通信方法

方法总结

img

demo小测试

Android应用间三种通信方式详细流程解析

1. Intent通信方式

流程概述

Intent通信是Android中最基础的组件间通信方式,通过显式或隐式Intent启动目标Activity并传递数据。

详细流程

ApplicationA (发送方)
public void intentToApplicationB(View view) {
    // 1. 创建Intent对象
    Intent intent = new Intent();
    
    // 2. 设置Action (关键步骤)
    intent.setAction("com.example.ACTION_RECEIVE_INTENT");
    
    // 3. 添加Category (必须与接收方匹配)
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    
    // 4. 添加要传递的数据
    intent.putExtra("INTENT_MSG", "来自A的Intent消息");
    
    // 5. 指定目标包名 (提高路由精确度)
    intent.setPackage("com.example.applicationb");

    // 6. 检查是否存在能处理该Intent的组件
    if (getPackageManager().resolveActivity(intent, 0) != null) {
        // 7. 启动目标Activity
        startActivity(intent);
    } else {
        Toast.makeText(this, "未找到ApplicationB", Toast.LENGTH_SHORT).show();
    }
}
ApplicationB (接收方)

AndroidManifest.xml配置:

<activity android:name=".MainActivity" android:exported="true">
    <!-- 启动器配置 -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    
    <!-- Intent接收配置 -->
    <intent-filter>
        <action android:name="com.example.ACTION_RECEIVE_INTENT" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

接收处理代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    // 初始化UI组件
    tvIntent = findViewById(R.id.tv_intent);
    
    // 1. 处理启动时的Intent
    handleIntentMessage(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // 2. 处理新的Intent (Activity已在运行时)
    handleIntentMessage(intent);
}

private void handleIntentMessage(Intent intent) {
    // 3. 检查Intent的Action
    if (intent != null && "com.example.ACTION_RECEIVE_INTENT".equals(intent.getAction())) {
        // 4. 提取传递的数据
        String message = intent.getStringExtra("INTENT_MSG");
        if (message != null) {
            // 5. 更新UI显示消息
            tvIntent.setText(message);
        }
    }
}

Intent通信特点

  • 单向通信:只能从A发送到B
  • 即时性:消息立即传递
  • 生命周期:会启动或激活目标Activity
  • 数据限制:适合传递少量数据

2. AIDL通信方式

在这里插入图片描述

流程概述

AIDL(Android Interface Definition Language)通过Service实现跨进程通信,支持远程方法调用。

详细流程

ApplicationA (客户端)
// AIDL代理对象
private IMyAidlInterface aidlProxy;
private boolean isAidlBound = false;

// Service连接回调
private ServiceConnection aidlServiceConn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        // 1. 获取AIDL接口代理
        aidlProxy = IMyAidlInterface.Stub.asInterface(service);
        isAidlBound = true;
        Toast.makeText(MainActivity.this, "AIDL服务绑定成功,可发送消息", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        // 2. 连接断开时清理
        aidlProxy = null;
        isAidlBound = false;
    }
};

public void aidlToApplicationB(View view) {
    if (isAidlBound && aidlProxy != null) {
        // 3. 如果已绑定,直接调用远程方法
        try {
            aidlProxy.sendAidlMessage("来自A的AIDL消息");
            Toast.makeText(this, "AIDL消息发送成功", Toast.LENGTH_SHORT).show();
        } catch (RemoteException e) {
            Toast.makeText(this, "AIDL消息发送失败", Toast.LENGTH_SHORT).show();
        }
    } else {
        // 4. 如果未绑定,先绑定服务
        Intent serviceIntent = new Intent();
        serviceIntent.setAction("com.example.ACTION_AIDL_SERVICE");
        serviceIntent.setPackage("com.example.applicationb");
        serviceIntent.addCategory(Intent.CATEGORY_DEFAULT);
        
        // 5. 绑定远程服务
        bindService(serviceIntent, aidlServiceConn, BIND_AUTO_CREATE);
        Toast.makeText(this, "正在绑定AIDL服务,绑定成功后可发送", Toast.LENGTH_SHORT).show();
    }
}
ApplicationB (服务端)

MyAidlService.java:

public class MyAidlService extends Service {
    // 1. 实现AIDL接口
    private final IMyAidlInterface.Stub aidlStub = new IMyAidlInterface.Stub() {
        @Override
        public void sendAidlMessage(String message) throws RemoteException {
            // 2. 收到远程调用后,通过本地广播通知MainActivity
            Intent broadcastIntent = new Intent("com.example.ACTION_RECEIVE_AIDL");
            broadcastIntent.putExtra("AIDL_MSG", message != null ? message : "空AIDL消息");
            
            // 3. 发送本地广播
            LocalBroadcastManager.getInstance(MyAidlService.this)
                .sendBroadcast(broadcastIntent);
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        // 4. 返回AIDL Stub给客户端
        return aidlStub;
    }
}

MainActivity.java (接收广播):

// 5. 本地广播接收器
private BroadcastReceiver aidlReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if ("com.example.ACTION_RECEIVE_AIDL".equals(intent.getAction())) {
            // 6. 从广播中提取消息
            String message = intent.getStringExtra("AIDL_MSG");
            // 7. 更新UI
            tvAidl.setText(message);
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // 8. 注册本地广播接收器
    IntentFilter aidlFilter = new IntentFilter("com.example.ACTION_RECEIVE_AIDL");
    LocalBroadcastManager.getInstance(this).registerReceiver(aidlReceiver, aidlFilter);
}

AndroidManifest.xml配置:

<service android:name=".MyAidlService" android:exported="true">
    <intent-filter>
        <action android:name="com.example.ACTION_AIDL_SERVICE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

AIDL通信特点

  • 双向通信:支持远程方法调用和回调
  • 持久连接:Service保持运行状态
  • 跨进程:真正的进程间通信
  • 复杂数据:支持复杂数据类型传递

3. Socket通信方式

流程概述

Socket通信通过TCP/IP协议实现网络层面的数据传输,是最底层的通信方式。

详细流程

ApplicationB (服务器端)
private void startSocketServer() {
    // 1. 在后台线程启动Socket服务器
    new Thread(new Runnable() {
        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                // 2. 创建服务器Socket,监听12345端口
                serverSocket = new ServerSocket(12345);
                
                // 3. 循环等待客户端连接
                while (!isFinishing()) {
                    // 4. 接受客户端连接 (阻塞等待)
                    Socket clientSocket = serverSocket.accept();
                    
                    // 5. 获取输入流
                    InputStream inputStream = clientSocket.getInputStream();

                    // 6. 读取客户端发送的数据
                    byte[] buffer = new byte[1024];
                    int length = inputStream.read(buffer);
                    
                    // 7. 解析消息
                    final String message = new String(buffer, 0, length, "UTF-8");

                    // 8. 切换到主线程更新UI
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            tvSocket.setText(message);
                        }
                    });

                    // 9. 关闭连接资源
                    inputStream.close();
                    clientSocket.close();
                }
            } catch (final IOException e) {
                // 10. 异常处理
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvSocket.setText("Socket服务器异常");
                    }
                });
            } finally {
                // 11. 清理服务器Socket
                try {
                    if (serverSocket != null) serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}
ApplicationA (客户端)
public void socketToApplicationB(View view) {
    // 1. 在后台线程进行网络操作
    new Thread(new Runnable() {
        @Override
        public void run() {
            Socket socket = null;
            OutputStream outputStream = null;
            try {
                // 2. 连接到服务器 (localhost:12345)
                socket = new Socket("localhost", 12345);
                
                // 3. 获取输出流
                outputStream = socket.getOutputStream();
                
                // 4. 准备要发送的消息
                String message = "来自A的Socket消息";
                
                // 5. 发送消息 (转换为字节流)
                outputStream.write(message.getBytes("UTF-8"));
                outputStream.flush();

                // 6. 切换到主线程显示成功提示
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "Socket消息发送成功", Toast.LENGTH_SHORT).show();
                    }
                });
                
            } catch (final IOException e) {
                // 7. 异常处理 (连接失败等)
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "Socket发送失败(B未启动?)", Toast.LENGTH_SHORT).show();
                    }
                });
            } finally {
                // 8. 清理资源
                try {
                    if (outputStream != null) outputStream.close();
                    if (socket != null) socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

Socket通信特点

  • 网络通信:基于TCP/IP协议
  • 实时性:支持实时数据传输
  • 灵活性:可传输任意格式数据
  • 复杂性:需要处理网络异常和线程同步
Logo

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

更多推荐