Android系统基于Linux内核,采用多进程架构设计。每个Android应用默认运行在独立的进程中,拥有独立的虚拟机实例和内存空间。进程间的内存隔离机制保证了系统的稳定性和安全性,但同时也带来了进程间通信的挑战。
Android提供了多种IPC机制,可以从不同维度进行分类:
按实现层次分类:
按传输数据类型分类:
Binder是Android最重要的IPC机制,采用Client-Server架构模式:
// 1. 服务端注册服务
public class MyService extends Service {
private final IMyInterface.Stub mBinder = new IMyInterface.Stub() {
@Override
public String getData() throws RemoteException {
return "Hello from service";
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
// 2. 客户端绑定服务
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IMyInterface.Stub.asInterface(service);
try {
String result = mService.getData();
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
Binder采用mmap内存映射机制,实现进程间的高效数据传输:
// Binder内存映射示意
static int binder_mmap(struct file *filp, struct vm_area_struct *vma) {
// 分配内核缓冲区
area = alloc_vm_area(vma->vm_end - vma->vm_start);
// 建立用户空间到内核空间的映射
ret = map_vm_area(area, PAGE_KERNEL, &pages);
return ret;
}
AIDL(Android Interface Definition Language)是Android提供的IDL语言,用于定义进程间接口:
// IBookManager.aidl
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
void registerListener(IOnNewBookArrivedListener listener);
void unregisterListener(IOnNewBookArrivedListener listener);
}
// IOnNewBookArrivedListener.aidl
interface IOnNewBookArrivedListener {
void onNewBookArrived(in Book newBook);
}
编译AIDL文件后,会生成对应的Java接口文件:
public interface IBookManager extends android.os.IInterface {
// 内部抽象类Stub,继承Binder并实现IBookManager接口
public static abstract class Stub extends android.os.Binder
implements IBookManager {
// 创建代理对象
public static IBookManager asInterface(android.os.IBinder obj) {
if (obj == null) return null;
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin != null && iin instanceof IBookManager) {
return (IBookManager) iin;
}
return new Proxy(obj);
}
// 处理跨进程调用
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply, int flags) {
switch (code) {
case TRANSACTION_getBookList: {
// 反序列化参数并调用实际方法
List<Book> result = this.getBookList();
// 序列化结果并返回
reply.writeTypedList(result);
return true;
}
}
}
}
// 代理类Proxy,负责打包参数并发起远程调用
private static class Proxy implements IBookManager {
@Override
public List<Book> getBookList() throws RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
// 发起远程调用
mRemote.transact(TRANSACTION_getBookList, _data, _reply, 0);
_reply.readException();
// 读取返回结果
List<Book> _result = _reply.createTypedArrayList(Book.CREATOR);
return _result;
} finally {
_reply.recycle();
_data.recycle();
}
}
}
}
public class BookManagerService extends Service {
private final CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
private final RemoteCallbackList<IOnNewBookArrivedListener> mListeners =
new RemoteCallbackList<>();
private final IBookManager.Stub mBinder = new IBookManager.Stub() {
@Override
public List<Book> getBookList() throws RemoteException {
// 耗时操作需要在工作线程执行
return mBookList;
}
@Override
public void addBook(Book book) throws RemoteException {
mBookList.add(book);
// 通知所有监听器
notifyNewBookArrived(book);
}
};
private void notifyNewBookArrived(Book book) {
final int count = mListeners.beginBroadcast();
for (int i = 0; i < count; i++) {
try {
mListeners.getBroadcastItem(i).onNewBookArrived(book);
} catch (RemoteException e) {
e.printStackTrace();
}
}
mListeners.finishBroadcast();
}
}
private final IBookManager.Stub mBinder = new IBookManager.Stub() {
@Override
public void addBook(Book book) throws RemoteException {
// 权限检查
int check = checkCallingOrSelfPermission("com.example.permission.ACCESS_BOOK");
if (check == PackageManager.PERMISSION_DENIED) {
throw new SecurityException("Permission denied");
}
// 包名检查
String packageName = getPackageManager().getNameForUid(getCallingUid());
if (!isPackageAllowed(packageName)) {
throw new SecurityException("Package not allowed");
}
mBookList.add(book);
}
};
Messenger是基于Handler和Message的轻量级IPC方案,适用于简单的消息传递:
// 服务端
public class MessengerService extends Service {
private static final int MSG_SAY_HELLO = 1;
// Handler处理客户端消息
private static class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Log.d(TAG, "Hello from client: " + msg.getData().getString("msg"));
// 回复客户端
try {
Message reply = Message.obtain(null, MSG_SAY_HELLO);
Bundle data = new Bundle();
data.putString("reply", "Hello from server");
reply.setData(data);
msg.replyTo.send(reply);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
private final Messenger mMessenger = new Messenger(new IncomingHandler());
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
// 客户端
public class MessengerClient {
private Messenger mService;
private Messenger mReplyMessenger = new Messenger(new ReplyHandler());
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
sendMessage();
}
};
private void sendMessage() {
try {
Message msg = Message.obtain(null, MSG_SAY_HELLO);
Bundle data = new Bundle();
data.putString("msg", "Hello from client");
msg.setData(data);
msg.replyTo = mReplyMessenger; // 设置回复Messenger
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
特性 | Messenger | AIDL |
---|---|---|
复杂度 | 简单 | 复杂 |
性能 | 较低 | 高 |
并发支持 | 串行处理 | 支持并发 |
数据类型 | 限制较多 | 支持复杂类型 |
适用场景 | 简单消息传递 | 复杂业务逻辑 |
ContentProvider是Android提供的标准化数据共享机制:
public class BookProvider extends ContentProvider {
private static final String AUTHORITY = "com.example.provider.book";
private static final int BOOK_DIR = 0;
private static final int BOOK_ITEM = 1;
private static UriMatcher sUriMatcher;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
sUriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
switch (sUriMatcher.match(uri)) {
case BOOK_DIR:
return queryAllBooks();
case BOOK_ITEM:
long id = ContentUris.parseId(uri);
return queryBookById(id);
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if (sUriMatcher.match(uri) != BOOK_DIR) {
throw new IllegalArgumentException("Unknown URI: " + uri);
}
long id = insertBook(values);
if (id > 0) {
Uri newUri = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
return null;
}
}
<provider
android:name=".BookProvider"
android:authorities="com.example.provider.book"
android:permission="com.example.permission.READ_BOOK"
android:readPermission="com.example.permission.READ_BOOK"
android:writePermission="com.example.permission.WRITE_BOOK"
android:exported="true" />
<permission
android:name="com.example.permission.READ_BOOK"
android:protectionLevel="normal" />
Socket适用于网络通信和大数据传输:
// 服务端
public class SocketServer {
private ServerSocket mServerSocket;
private ExecutorService mExecutor = Executors.newCachedThreadPool();
public void startServer() {
try {
mServerSocket = new ServerSocket(8888);
while (true) {
Socket clientSocket = mServerSocket.accept();
mExecutor.execute(new ClientHandler(clientSocket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class ClientHandler implements Runnable {
private Socket mSocket;
public ClientHandler(Socket socket) {
mSocket = socket;
}
@Override
public void run() {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(mSocket.getInputStream()));
PrintWriter writer = new PrintWriter(
mSocket.getOutputStream(), true)) {
String inputLine;
while ((inputLine = reader.readLine()) != null) {
// 处理客户端请求
String response = processRequest(inputLine);
writer.println(response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 客户端
public class SocketClient {
public void connectToServer() {
try (Socket socket = new Socket("localhost", 8888);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
writer.println("Hello Server");
String response = reader.readLine();
Log.d(TAG, "Server response: " + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Android还支持LocalSocket进行同设备内的进程间通信:
// 服务端
public class LocalSocketServer {
private LocalServerSocket mServerSocket;
public void startServer() {
try {
mServerSocket = new LocalServerSocket("my_socket");
while (true) {
LocalSocket clientSocket = mServerSocket.accept();
handleClient(clientSocket);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 客户端
public class LocalSocketClient {
public void connect() {
try {
LocalSocket socket = new LocalSocket();
socket.connect(new LocalSocketAddress("my_socket"));
// 数据传输
} catch (IOException e) {
e.printStackTrace();
}
}
}
Android提供了多种广播机制:
// 发送广播
Intent intent = new Intent("com.example.MY_BROADCAST");
intent.putExtra("data", "Hello");
sendBroadcast(intent);
// 接收广播
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("data");
Log.d(TAG, "Received: " + data);
}
}
// 发送有序广播
sendOrderedBroadcast(intent, null, resultReceiver, null,
Activity.RESULT_OK, null, null);
// 高优先级接收器
<receiver android:name=".HighPriorityReceiver"
android:priority="1000">
<intent-filter>
<action android:name="com.example.MY_BROADCAST" />
</intent-filter>
</receiver>
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.sendBroadcast(intent);
manager.registerReceiver(receiver, intentFilter);
// 权限控制
sendBroadcast(intent, "com.example.permission.RECEIVE_BROADCAST");
// 限制接收者
intent.setPackage("com.example.targetapp");
sendBroadcast(intent);
// 多进程模式
SharedPreferences prefs = getSharedPreferences("config",
Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("key", "value");
editor.apply();
public class FileBasedIPC {
private RandomAccessFile mFile;
private FileChannel mChannel;
private FileLock mLock;
public void writeData(String data) {
try {
mFile = new RandomAccessFile("ipc_file.txt", "rw");
mChannel = mFile.getChannel();
mLock = mChannel.lock(); // 获取文件锁
mFile.writeUTF(data);
mFile.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
releaseLock();
}
}
private void releaseLock() {
try {
if (mLock != null) mLock.release();
if (mChannel != null) mChannel.close();
if (mFile != null) mFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
IPC方式 | 延迟(ms) | 吞吐量(MB/s) | 内存占用 | CPU占用 |
---|---|---|---|---|
Binder | 0.1-0.5 | 100-200 | 低 | 低 |
Socket | 1-5 | 50-100 | 中等 | 中等 |
管道 | 0.5-2 | 80-150 | 低 | 低 |
共享内存 | 0.05-0.1 | 500+ | 高 | 低 |
// AIDL接口设计中避免死锁
public interface IBookManager extends IInterface {
// 避免在回调中调用远程方法
void registerListener(IOnNewBookArrivedListener listener);
// 使用oneway避免同步等待
oneway void notifyDataChanged();
}
public class SafeServiceConnection implements ServiceConnection {
private WeakReference<Activity> mActivityRef;
public SafeServiceConnection(Activity activity) {
mActivityRef = new WeakReference<>(activity);
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Activity activity = mActivityRef.get();
if (activity != null && !activity.isFinishing()) {
// 安全的操作
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 清理资源
}
}
public class KeepAliveService extends Service {
private static final int NOTIFICATION_ID = 1001;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 前台服务保活
startForeground(NOTIFICATION_ID, createNotification());
// 双进程守护
startWatchdog();
return START_STICKY; // 服务被杀死后自动重启
}
private void startWatchdog() {
Intent intent = new Intent(this, WatchdogService.class);
startService(intent);
}
}
# 查看Binder统计信息
adb shell cat /proc/binder/stats
# 查看进程Binder信息
adb shell cat /proc/[pid]/binder/stats
# 监控Binder事务
adb shell cat /sys/kernel/debug/binder/transactions
常见问题及解决方案:
Android跨进程通信是构建复杂应用架构的基础技术。选择合适的IPC机制需要综合考虑性能要求、数据类型、安全需求和开发复杂度。在实际项目中,往往需要组合使用多种IPC方式来满足不同的业务需求。
掌握这些IPC机制的原理和最佳实践,不仅有助于构建高质量的Android应用,也是深入理解Android系统架构的重要途径。随着Android系统的不断演进,新的IPC机制和优化方案也在不断涌现,需要持续关注和学习。