Appearance
Android 组件间通信 - 全面详解
组件间通信是 Android 开发的核心技能,包括应用内通信和跨进程通信(IPC)。
目录
- 广播通信(BroadcastReceiver)
- Binder 通信(bindService)
- Messenger 通信(远程)
- AIDL 跨进程通信
- 事件总线(EventBus/Flow)
- SharedPreferences 共享数据
- 本地 Socket 通信
- 方案对比与选择
- 面试考点
1. 广播通信(BroadcastReceiver)
1.1 概述
广播是最简单的组件间通信方式,适用于单向通知场景。
特点:
- ✅ 松耦合
- ✅ 一对多通信
- ✅ 实现简单
- ❌ 单向通信
- ❌ 无法获取返回值
- ❌ 性能较差
1.2 应用内广播
kotlin
// 发送广播
class DataSender {
fun sendData(context: Context, data: String) {
val intent = Intent("com.example.DATA_UPDATED")
intent.putExtra("data", data)
// 限制为本应用
intent.setPackage(context.packageName)
context.sendBroadcast(intent)
}
}
// 接收广播
class DataReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val data = intent.getStringExtra("data")
// 处理数据
}
}
// 动态注册
class MainActivity : AppCompatActivity() {
private val receiver = DataReceiver()
override fun onResume() {
super.onResume()
registerReceiver(
receiver,
IntentFilter("com.example.DATA_UPDATED")
)
}
override fun onPause() {
super.onPause()
unregisterReceiver(receiver)
}
}1.3 跨应用广播
kotlin
// 发送方:发送可被其他应用接收的广播
fun sendCrossAppBroadcast(context: Context) {
val intent = Intent("com.example.PUBLIC_ACTION")
intent.putExtra("data", "公开数据")
// 需要其他应用声明权限
context.sendBroadcast(
intent,
"com.example.PUBLIC_BROADCAST_PERMISSION"
)
}
// 接收方:在 Manifest 中声明
// AndroidManifest.xml
<receiver
android:name=".PublicReceiver"
android:exported="true"
android:permission="com.example.PUBLIC_BROADCAST_PERMISSION">
<intent-filter>
<action android:name="com.example.PUBLIC_ACTION" />
</intent-filter>
</receiver>1.4 有序广播传递数据
kotlin
// 第一个接收器
class FirstReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// 设置结果
setResultCode(Activity.RESULT_OK)
setResultData("处理后的数据")
// 不拦截,继续传递
}
}
// 第二个接收器
class SecondReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// 获取上一个接收器的结果
val data = getResultData()
val code = getResultCode()
// 可以继续修改结果
setResultData("再次处理的数据")
// 拦截广播
abortBroadcast()
}
}2. Binder 通信(bindService)
2.1 概述
Binder 是 Android 最基础的 IPC 机制,通过 bindService 实现 Service 与客户端的通信。
特点:
- ✅ 高性能(同一进程内直接调用)
- ✅ 双向通信
- ✅ 可获取返回值
- ❌ 需要暴露 Service
- ⚠️ 跨进程有性能开销
2.2 同进程 Binder 通信
Service 实现:
kotlin
class MusicService : Service() {
// 本地 Binder
private val localBinder = LocalBinder()
inner class LocalBinder : Binder() {
fun getService(): MusicService = this@MusicService
}
override fun onBind(intent: Intent?): IBinder {
return localBinder
}
// 公开的方法
fun playMusic() {
Log.d("MusicService", "播放音乐")
}
fun pauseMusic() {
Log.d("MusicService", "暂停音乐")
}
fun getPlayState(): LiveData<PlayState> {
return _playState
}
private val _playState = MutableLiveData<PlayState>()
private var currentPlayState: PlayState = PlayState.STOPPED
enum class PlayState { STOPPED, PLAYING, PAUSED }
}客户端绑定:
kotlin
class MainActivity : AppCompatActivity() {
private var serviceBound = false
private var musicService: MusicService? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
serviceBound = true
val binder = service as MusicService.LocalBinder
musicService = binder.getService()
// 直接调用 Service 的方法
musicService?.playMusic()
// 观察状态变化
musicService?.getPlayState()?.observe(this@MainActivity) { state ->
updatePlayButton(state)
}
}
override fun onServiceDisconnected(name: ComponentName?) {
serviceBound = false
musicService = null
}
}
override fun onStart() {
super.onStart()
val intent = Intent(this, MusicService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
override fun onStop() {
super.onStop()
if (serviceBound) {
unbindService(connection)
serviceBound = false
}
}
private fun updatePlayButton(state: MusicService.PlayState) {
// 更新 UI
}
}2.3 跨进程 Binder 通信
Service 实现(返回 IBinder):
kotlin
class RemoteService : Service() {
// 跨进程使用 IBinder,不能直接返回 LocalBinder
private val remoteBinder = RemoteBinder()
inner class RemoteBinder : IBinder.Stub() {
override fun playMusic() {
// 执行播放
}
override fun pauseMusic() {
// 执行暂停
}
override fun getPlayState(): Int {
return currentState
}
}
override fun onBind(intent: Intent?): IBinder {
return remoteBinder
}
}客户端调用:
kotlin
class ClientActivity : AppCompatActivity() {
private var remoteService: IRemoteService? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// 将 IBinder 转换为接口
remoteService = IRemoteService.Stub.asInterface(service)
// 调用远程方法
remoteService?.playMusic()
}
override fun onServiceDisconnected(name: ComponentName?) {
remoteService = null
}
}
override fun onStart() {
super.onStart()
val intent = Intent("com.example.service.REMOTE")
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}2.4 带回调的 Binder 通信
kotlin
// 定义回调接口
interface Callback {
fun onResult(result: String)
}
// Service
class CallbackService : Service() {
private val binder = CallbackBinder()
inner class CallbackBinder : Binder() {
fun setCallback(callback: Callback?) {
this@CallbackService.callback = callback
}
fun doWork(data: String) {
// 执行工作
val result = process(data)
// 回调结果
callback?.onResult(result)
}
}
private var callback: Callback? = null
private fun process(data: String): String {
return "处理:$data"
}
}
// 客户端
class ClientActivity : AppCompatActivity() {
private var serviceBinder: CallbackService.CallbackBinder? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
serviceBinder = service as CallbackService.CallbackBinder
// 设置回调
serviceBinder?.setCallback(object : Callback {
override fun onResult(result: String) {
runOnUiThread {
showToast(result)
}
}
})
// 执行工作
serviceBinder?.doWork("测试数据")
}
override fun onServiceDisconnected(name: ComponentName?) {
serviceBinder = null
}
}
}3. Messenger 通信(远程)
3.1 概述
Messenger 基于 Handler 和 IBinder,适合跨进程通信,自动处理线程问题。
特点:
- ✅ 跨进程友好
- ✅ 自动处理线程
- ✅ 单向消息传递
- ❌ 性能低于直接 Binder
- ❌ 只能传递 Message
3.2 Service 端实现
kotlin
class MessengerService : Service() {
// 处理消息的 Handler
private val handler = Handler(Looper.getMainLooper()) { msg ->
when (msg.what) {
MSG_PLAY -> {
val data = msg.getData().getString("data")
playMusic(data)
// 发送回复
val replyMsg = Message.obtain(handler, MSG_REPLY)
replyMsg.getData().putString("result", "已播放")
try {
msg.replyTo?.send(0, replyMsg)
} catch (e: RemoteException) {
Log.e("MessengerService", "发送回复失败", e)
}
}
MSG_PAUSE -> {
pauseMusic()
}
}
true
}
// 创建 Messenger
private val messenger = Messenger(handler)
override fun onBind(intent: Intent?): IBinder {
return messenger.binder
}
private fun playMusic(data: String?) {
Log.d("MessengerService", "播放音乐:$data")
}
private fun pauseMusic() {
Log.d("MessengerService", "暂停音乐")
}
companion object {
const val MSG_PLAY = 1
const val MSG_PAUSE = 2
const val MSG_REPLY = 3
}
}3.3 客户端实现
kotlin
class ClientActivity : AppCompatActivity() {
private var serviceMessenger: Messenger? = null
private var clientHandler: Handler? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
serviceMessenger = Messenger(service)
// 创建接收回复的 Handler
clientHandler = Handler(Looper.getMainLooper()) { msg ->
when (msg.what) {
MSG_REPLY -> {
val result = msg.getData().getString("result")
showToast(result)
}
}
true
}
// 发送消息
sendMessage()
}
override fun onServiceDisconnected(name: ComponentName?) {
serviceMessenger = null
clientHandler = null
}
}
private fun sendMessage() {
val msg = Message.obtain()
msg.what = MSG_PLAY
msg.getData().putString("data", "音乐名称")
// 设置回复的 Messenger
msg.replyTo = Messenger(clientHandler)
try {
serviceMessenger?.send(msg)
} catch (e: RemoteException) {
Log.e("ClientActivity", "发送消息失败", e)
}
}
override fun onStart() {
super.onStart()
val intent = Intent(this, MessengerService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}3.4 Messenger 传递复杂数据
kotlin
// 使用 Bundle 传递复杂数据
val msg = Message.obtain()
msg.what = MSG_UPDATE_USER
val bundle = Bundle().apply {
putString("name", "张三")
putInt("age", 25)
putParcelable("user", UserParcelable("张三", 25))
putParcelableArrayList("users", arrayListOf(user1, user2))
}
msg.setData(bundle)
// 接收端
val bundle = msg.data
val name = bundle.getString("name")
val user = bundle.getParcelable<User>("user")4. AIDL 跨进程通信
4.1 概述
AIDL(Android Interface Definition Language)是 Android 提供的跨进程通信接口定义语言。
特点:
- ✅ 真正的跨进程 RPC
- ✅ 类型安全
- ✅ 支持复杂数据类型
- ✅ 支持异步回调
- ❌ 开发相对复杂
4.2 定义 AIDL 接口
创建 IMyService.aidl:
aidl
// IMyService.aidl
package com.example.aidl;
import com.example.aidl.User;
import com.example.aidl.Callback;
interface IMyService {
// 基本类型方法
String getData();
int add(int a, int b);
// 复杂类型方法
User getUser(long id);
List<User> getAllUsers();
// 带回调的方法
void doWork(String data, Callback callback);
// 监听器
void registerCallback(Callback callback);
void unregisterCallback(Callback callback);
}创建 User.aidl:
aidl
// User.aidl
package com.example.aidl;
parcelable User;创建 Callback.aidl:
aidl
// Callback.aidl
package com.example.aidl;
interface Callback {
void onResult(String result);
void onError(String error);
}4.3 服务端实现
kotlin
class AidlService : Service() {
private val aidlBinder = BinderImpl()
inner class BinderImpl : IMyService.Stub() {
override fun getData(): String {
return "来自 Service 的数据"
}
override fun add(a: Int, b: Int): Int {
return a + b
}
override fun getUser(id: Long): User {
return User(id, "用户$id", "$id@example.com")
}
override fun getAllUsers(): List<User> {
return listOf(
User(1, "用户 1", "1@example.com"),
User(2, "用户 2", "2@example.com")
)
}
override fun doWork(data: String?, callback: Callback?) {
// 模拟异步操作
Handler(Looper.getMainLooper()).postDelayed({
try {
callback?.onResult("处理完成:$data")
} catch (e: RemoteException) {
Log.e("AidlService", "回调失败", e)
}
}, 1000)
}
// 管理回调列表
private val callbacks = CopyOnWriteArrayList<Callback>()
override fun registerCallback(callback: Callback?) {
callback?.let { callbacks.add(it) }
}
override fun unregisterCallback(callback: Callback?) {
callback?.let { callbacks.remove(it) }
}
// 通知所有回调
private fun notifyAllCallbacks(result: String) {
for (callback in callbacks) {
try {
callback.onResult(result)
} catch (e: RemoteException) {
Log.e("AidlService", "通知回调失败", e)
}
}
}
}
override fun onBind(intent: Intent?): IBinder {
return aidlBinder
}
}4.4 客户端实现
kotlin
class AidlClientActivity : AppCompatActivity() {
private var myService: IMyService? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
myService = IMyService.Stub.asInterface(service)
// 调用 AIDL 方法
callAidlMethods()
// 注册回调
registerCallback()
}
override fun onServiceDisconnected(name: ComponentName?) {
myService = null
}
}
private fun callAidlMethods() {
try {
// 基本方法
val data = myService?.getData()
val sum = myService?.add(10, 20)
// 复杂类型
val user = myService?.getUser(1)
val users = myService?.getAllUsers()
// 带回调
myService?.doWork("测试数据", object : Callback.Stub() {
override fun onResult(result: String?) {
runOnUiThread {
showToast(result)
}
}
override fun onError(error: String?) {
runOnUiThread {
showError(error)
}
}
})
} catch (e: RemoteException) {
Log.e("AidlClient", "调用失败", e)
}
}
private fun registerCallback() {
myService?.registerCallback(object : Callback.Stub() {
override fun onResult(result: String?) {
runOnUiThread {
updateUI(result)
}
}
override fun onError(error: String?) {
runOnUiThread {
showError(error)
}
}
})
}
override fun onStart() {
super.onStart()
val intent = Intent(this, AidlService::class.java)
intent.setPackage("com.example.aidl") // 指定包名
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
override fun onDestroy() {
super.onDestroy()
if (serviceBound) {
unbindService(connection)
}
}
}4.5 AIDL 数据类型支持
aidl
// 基本类型(不需要特别处理)
int, long, float, double, boolean, String
// List(元素必须是基本类型或 AIDL/Parcelable)
List<String>
List<User>
// Map(键值对必须是基本类型或 AIDL/Parcelable)
Map<String, User>
// 自定义类型
parcelable User
parcelable UserList
// 接口类型
interface Callback4.6 AIDL 优化
aidl
// 优化 1:使用 oneway 关键字(异步调用)
oneway void notifyUpdated(String data);
// 优化 2:批量操作
List<User> getUsersByIds(List<Long> ids);
// 优化 3:避免频繁调用
void startObserving(Callback callback);
void stopObserving(Callback callback);5. 事件总线
5.1 EventBus(第三方库)
添加依赖:
gradle
dependencies {
implementation 'org.greenrobot:eventbus:3.3.1'
}使用示例:
kotlin
// 定义事件
data class UserLoggedInEvent(val userId: Long)
data class DataRefreshedEvent(val data: List<String>)
// 发送事件
class EventSender {
fun login(userId: Long) {
EventBus.getDefault().post(UserLoggedInEvent(userId))
}
fun refreshData(data: List<String>) {
EventBus.getDefault().post(DataRefreshedEvent(data))
}
}
// 接收事件
class EventReceiverActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
EventBus.getDefault().register(this)
}
@MainThread
fun onEventMainThread(event: UserLoggedInEvent) {
showToast("用户登录:${event.userId}")
}
fun onEvent(DataRefreshedEvent event) {
// 在事件发生的线程中执行
updateData(event.data)
}
@Suppress("unused")
fun onEventAsync(DataRefreshedEvent event) {
// 在后台线程执行
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
}
}5.2 Kotlin Flow(推荐)
使用 StateFlow:
kotlin
// 创建共享的 StateFlow
object EventBus {
private val _events = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = _events.asSharedFlow()
suspend fun emit(event: Event) {
_events.emit(event)
}
}
sealed class Event {
data class UserLoggedIn(val userId: Long) : Event()
data class DataRefreshed(val data: List<String>) : Event()
}
// 发送事件
suspend fun loginUser(userId: Long) {
EventBus.emit(Event.UserLoggedIn(userId))
}
// 接收事件(在 ViewModel 中)
class MyViewModel : ViewModel() {
val events = EventBus.events
fun login(userId: Long) {
viewModelScope.launch {
EventBus.emit(Event.UserLoggedIn(userId))
}
}
}
// 在 Activity 中观察
class MyActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.events.collect { event ->
when (event) {
is Event.UserLoggedIn -> {
showToast("用户登录:${event.userId}")
}
is Event.DataRefreshed -> {
updateData(event.data)
}
}
}
}
}
}
}5.3 LiveData(应用内)
kotlin
// 创建 LiveData 事件
class EventLiveData<T> : MutableLiveData<T>() {
fun postEvent(event: T) {
value = event
}
}
// ViewModel
class MyViewModel : ViewModel() {
val loginEvent = EventLiveData<Long>()
val refreshEvent = EventLiveData<List<String>>()
fun onLogin(userId: Long) {
loginEvent.postEvent(userId)
}
fun onRefresh(data: List<String>) {
refreshEvent.postEvent(data)
}
}
// Activity
class MyActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.loginEvent.observe(this) { userId ->
showToast("用户登录:$userId")
}
viewModel.refreshEvent.observe(this) { data ->
updateData(data)
}
}
}6. SharedPreferences 共享数据
6.1 基础使用
kotlin
// 写入数据
fun saveData(context: Context) {
val prefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
prefs.edit().apply {
putString("name", "张三")
putInt("age", 25)
putBoolean("isLogin", true)
putStringSet("tags", setOf("tag1", "tag2"))
apply() // 异步提交
// commit() // 同步提交
}
}
// 读取数据
fun loadData(context: Context) {
val prefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
val name = prefs.getString("name", "")
val age = prefs.getInt("age", 0)
val isLogin = prefs.getBoolean("isLogin", false)
val tags = prefs.getStringSet("tags", emptySet())
}6.2 监听数据变化
kotlin
class SharedPreferencesObserver(
private val prefs: SharedPreferences,
private val key: String,
private val listener: (String?) -> Unit
) {
private val sharedPreferenceListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPrefs, key ->
if (key == this.key) {
listener(sharedPrefs.getString(key, null))
}
}
fun register() {
prefs.registerOnSharedPreferenceChangeListener(sharedPreferenceListener)
}
fun unregister() {
prefs.unregisterOnSharedPreferenceChangeListener(sharedPreferenceListener)
}
}
// 使用
class Activity : AppCompatActivity() {
private val observer: SharedPreferencesObserver? = null
override fun onResume() {
super.onResume()
observer?.register()
}
override fun onPause() {
super.onPause()
observer?.unregister()
}
}6.3 DataStore(推荐替代方案)
kotlin
// 添加依赖
// implementation 'androidx.datastore:datastore-preferences:1.0.0'
// 定义 preferences
val prefs = dataStore.data.map { preferences ->
PreferencesFacade.wrap(preferences)
}
// 读取
lifecycleScope.launch {
prefs.collect { preferences ->
val name = preferences.getString("name") ?: ""
val age = preferences.getInt("age") ?: 0
}
}
// 写入
lifecycleScope.launch {
dataStore.edit { preferences ->
preferences["name"] = "张三"
preferences["age"] = 25
}
}7. 本地 Socket 通信
7.1 概述
LocalSocket 用于同一设备上的进程间通信,适合大数据传输。
特点:
- ✅ 高性能
- ✅ 支持大数据传输
- ✅ 流式通信
- ❌ 实现复杂
- ❌ 需要处理连接管理
7.2 Server 端实现
kotlin
class SocketServer {
private var serverSocket: LocalServerSocket? = null
private var isRunning = false
companion object {
const val SOCKET_FILE = "myapp.socket"
}
fun start(hostCallback: HostCallback) {
try {
// 清理旧的 socket 文件
val socketFile = File(File.context.cacheDir, SOCKET_FILE)
socketFile.delete()
serverSocket = LocalServerSocket(InetSocketAddress(socketFile))
isRunning = true
Thread {
while (isRunning) {
try {
val clientSocket = serverSocket?.accept()
clientSocket?.let {
Thread { handleClient(it, hostCallback) }.start()
}
} catch (e: Exception) {
if (isRunning) {
Log.e("SocketServer", "接受连接失败", e)
}
}
}
}.start()
} catch (e: Exception) {
Log.e("SocketServer", "启动失败", e)
}
}
private fun handleClient(socket: LocalSocket, callback: HostCallback) {
try {
val inputStream = socket.inputStream
val outputStream = socket.outputStream
// 接收数据
val buffer = ByteArray(1024)
val length = inputStream.read(buffer)
val data = String(buffer, 0, length)
// 处理请求
val response = processRequest(data)
// 发送响应
outputStream.write(response.toByteArray())
outputStream.flush()
} catch (e: Exception) {
Log.e("SocketServer", "处理客户端失败", e)
} finally {
socket.close()
}
}
private fun processRequest(request: String): String {
// 处理请求逻辑
return "响应:$request"
}
fun stop() {
isRunning = false
serverSocket?.close()
serverSocket = null
}
interface HostCallback {
fun onClientConnected()
fun onClientDisconnected()
}
}7.3 Client 端实现
kotlin
class SocketClient {
fun sendRequest(context: Context, request: String, callback: ResponseCallback) {
Thread {
val socketFile = File(context.cacheDir, SocketServer.SOCKET_FILE)
var socket: LocalSocket? = null
try {
socket = LocalSocket()
socket.connect(InetSocketAddress(socketFile))
val outputStream = socket.outputStream
val inputStream = socket.inputStream
// 发送请求
outputStream.write(request.toByteArray())
outputStream.flush()
// 接收响应
val buffer = ByteArray(1024)
val length = inputStream.read(buffer)
val response = String(buffer, 0, length)
// 回调响应
callback.onSuccess(response)
} catch (e: Exception) {
callback.onError(e.message)
} finally {
socket?.close()
}
}.start()
}
interface ResponseCallback {
fun onSuccess(response: String)
fun onError(error: String?)
}
}7.4 使用示例
kotlin
// Server(在 Service 中)
class SocketService : Service() {
private val server = SocketServer()
override fun onCreate() {
super.onCreate()
server.start(object : SocketServer.HostCallback {
override fun onClientConnected() {
Log.d("SocketService", "客户端连接")
}
override fun onClientDisconnected() {
Log.d("SocketService", "客户端断开")
}
})
}
override fun onDestroy() {
server.stop()
super.onDestroy()
}
}
// Client
class MainActivity : AppCompatActivity() {
private val client = SocketClient()
fun sendRequest() {
client.sendRequest(this, "Hello Server", object : SocketClient.ResponseCallback {
override fun onSuccess(response: String) {
runOnUiThread {
showToast(response)
}
}
override fun onError(error: String?) {
runOnUiThread {
showError(error)
}
}
})
}
}8. 方案对比与选择
8.1 完整对比表
| 方案 | 通信方向 | 性能 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| BroadcastReceiver | 单向 | 低 | 低 | 简单通知 |
| Binder (同进程) | 双向 | 高 | 中 | 同进程通信 |
| Binder (跨进程) | 双向 | 中 | 中 | 简单 IPC |
| Messenger | 单向 | 中 | 中 | 跨进程消息 |
| AIDL | 双向 | 中 | 高 | 复杂 IPC |
| EventBus/Flow | 单向 | 高 | 低 | 应用内事件 |
| SharedPreferences | 单向 | 中 | 低 | 配置共享 |
| LocalSocket | 双向 | 高 | 高 | 大数据传输 |
8.2 选择指南
┌───────────────────────────────────────────────┐
│ 组件间通信方案选择 │
├───────────────────────────────────────────────┤
│ │
│ 应用内通信: │
│ ┌───────────────────────────────────┐ │
│ │ 简单通知 → BroadcastReceiver │ │
│ │ 事件分发 → Flow/EventBus │ │
│ │ 配置共享 → SharedPreferences │ │
│ │ 直接调用 → Binder │ │
│ └───────────────────────────────────┘ │
│ │
│ 跨进程通信: │
│ ┌───────────────────────────────────┐ │
│ │ 简单 RPC → Binder │ │
│ │ 消息传递 → Messenger │ │
│ │ 复杂接口 → AIDL │ │
│ │ 大数据传输 → LocalSocket │ │
│ └───────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────┘8.3 最佳实践
kotlin
// 1. 优先使用应用内通信方案
// 2. 跨进程尽量减少调用频率
// 3. 大数据使用文件+URI 传递
// 4. 异步操作使用回调或 Flow
// 5. 注意权限和安全问题
// 推荐架构:
// ViewModel + Flow/LiveData(应用内状态管理)
// AIDL(跨进程接口定义)
// WorkManager(后台任务)9. 面试考点
9.1 基础题
Q1: Android 有哪些组件间通信方式?
A:
- 广播(BroadcastReceiver)
- Binder(bindService)
- Messenger
- AIDL
- 事件总线(EventBus)
- SharedPreferences
- LocalSocket
Q2: Binder 和 AIDL 的区别?
A:
- Binder 是底层 IPC 机制
- AIDL 基于 Binder,提供更友好的接口定义
- 同进程用 Binder,跨进程用 AIDL
Q3: Messenger 的原理?
A: Messenger 基于 Handler 和 IBinder,通过 Message 传递数据。
9.2 进阶题
Q4: 什么时候使用 AIDL?
A: 当需要跨进程调用复杂接口,且需要类型安全时使用 AIDL。
Q5: EventBus 和 Flow 的区别?
A:
- EventBus 是第三方库,API 简单
- Flow 是 Kotlin 官方协程,支持背压
- Flow 推荐使用
Q6: 如何优化 IPC 性能?
A:
- 减少调用频率
- 批量操作
- 使用 oneway 异步调用
- 避免传递大数据
9.3 高级题
Q7: Binder 的工作原理?
A: Binder 通过内核空间映射实现进程间内存共享,减少数据拷贝。
Q8: AIDL 如何支持异步回调?
A: 使用 oneway 关键字定义异步方法,或使用 Callback 接口。
Q9: LocalSocket 和 Socket 的区别?
A: LocalSocket 使用 Unix Domain Socket,在同一设备上性能更高。
总结
组件间通信方案丰富,选择要点:
- 应用内:优先 Flow/LiveData,简单通知用广播
- 跨进程:简单用 Binder,复杂用 AIDL
- 大数据:LocalSocket 或文件+URI
- 配置共享:SharedPreferences 或 DataStore
- 性能敏感:减少 IPC 调用,批量操作
根据场景选择合适的方案,构建高效的 Android 应用架构。