看源码的时候可以用uml图辅助理解
多进程
为什么多进程
- 突破内存限制:Android系统在内存不足时,会优先杀占用内存多的进程
- 功能稳定性:把一些功能放到独立的进程中,保证进程功能的纯粹性和稳定性
- 规避系统内存泄漏:独立的WebView进程阻隔内存泄漏问题
- 隔离风险:不稳定功能放到子进程,保证主进程的稳定性
Android中的进程间通信
- Binder
- Socket
- 管道:handler
- 共享内存
- 信号:
- ANR监控
- matrix、xcrash、友盟apm
binder的优势
- 一次拷贝
- 将内核空间内存映射到用户空间
- a发送数据到b,binder直接将数据拷贝到与b共享的内存空间中
- cs架构,稳定性好
- 安全,有身份验证(交换pid,由内核完成
AIDL
四大组件
bindService一共几次IPC
- 客户端与ServiceManager交互获得AMS的IBinder
- 客户端通过AMS的IBinder请求bindService
- AMS与服务进程通信,调用onBind,获取IBinder
- 服务端把IBinder交给AMS,先ServiceManager交互获得AMS的IBinder
- 服务端通过AMS的IBinder发布自己的IBinder给AMS
- AMS与客户端通信,转发服务端的IBinder(代理BinderProxy)

binder数据传输的大小限制
- 10241024-40962
- BIND_VM_SIZE = 1M - sysconf(_SC_PAGE_SIZE) * 2
- aidl
- 异步传输:oneway,BIND_VM_SIZE/2
- 同步传输:BIND_VM_SIZE
Binder其他知识
Binder驱动
binder_init
通过misc_register注册特殊设备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| static const struct file_operations binder_fops = { .owner = THIS_MODULE, .poll = binder_poll, .unlocked_ioctl = binder_ioctl, .compat_ioctl = binder_ioctl, .mmap = binder_mmap, .open = binder_open, .flush = binder_flush, .release = binder_release, };
static struct miscdevice binder_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "binder", .fops = &binder_fops };
|
open -> binder_open
- 创建binder_proc结构并初始化
- 保存进程信息
- 加锁,计数++,hlist_add_head
- filp文件指针的private_data指向binder_proc
mmap -> binder_mmap
1 2 3 4
| proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
proc->free_async_space = proc->buffer_size / 2;
|
ioctl -> binder_ioctl
ioctl命令 |
数据类型 |
操作 |
使用场景 |
BINDER_WRITE_READ |
struct binder_write_read |
收发Binder IPC数据 |
Binder读写交互场景,IPC.talkWithDriver |
BINDER_SET_MAX_THREADS |
__u32 |
设置Binder线程最大个数 |
|
BINDER_SET_CONTEXT_MGR |
__s32 |
设置Service Manager节点 |
servicemanager进程成为上下文管理者,binder_become_context_manager() |
BINDER_THREAD_EXIT |
__s32 |
释放Binder线程 |
|
BINDER_VERSION |
struct binder_version |
获取Binder版本信息 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); binder_lock(__func__); thread = binder_get_thread(proc);
switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read(filp, cmd, arg, thread); if (ret) goto err; break; } err: if (thread) thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; binder_unlock(__func__); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); err_unlocked: trace_binder_ioctl_done(ret); return ret; }
|
- binder_get_thread
- 从一颗红黑树上根据pid找当前线程
- 如果没有,则创建节点
- binder_ioctl_write_read
- copy_from_user读取bwr
- 检查读写缓存中是否有数据,如果有,就执行读写
- copy_to_user将bwr写回用户空间
Binder层次结构

Binder通信模型

通信码
- 从ICP层至内核:
BC_
请求码
- 从内核到IPC层:
BR_
响应码
过程

binder_thread_write
循环根据cmd处理请求
BC_FREE_BUFFER
- 通过mmap映射内存,ServiceManager映射空间为128K,Binder应用进程为
1M-8K
- allocated_buffers和free_buffers是两棵红黑树,分别存放已分配内存和未分配内存。分配内存时使用最佳适应算法。
BC_TRANSACTION
- 最常见的码,将交易转化成binder_work
- Client向Binder驱动发送请求数据
BC_REPLY
binder_thread_read
- 根据work和当前状态生成响应码,接下来由用户态进行处理
ServiceManager
- servicemanager是操作系统的一个可执行文件,在init.rc中启动
main
1 2 3 4 5 6 7 8 9 10 11
| int main(int argc, char **argv) { struct binder_state *bs; bs = binder_open(128*1024); binder_become_context_manager(bs); binder_loop(bs, svcmgr_handler); return 0; }
|
binder_open
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| struct binder_state *binder_open(size_t mapsize) { struct binder_state *bs; struct binder_version vers;
bs = malloc(sizeof(*bs));
bs->fd = open("/dev/binder", O_RDWR);
bs->mapsize = mapsize; bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); return bs; }
|
binder_become_context_manager
1 2 3 4 5 6 7
| ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); -> binder_ioctl() -> binder_ioctl_set_ctx_mgr() ->
|
binder_loop
1 2 3 4 5 6
| readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(uint32_t)); for(;;) { res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); }
|
binder_write
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int binder_write(struct binder_state *bs, void *data, size_t len) { struct binder_write_read bwr; int res;
bwr.write_size = len; bwr.write_consumed = 0; bwr.write_buffer = (uintptr_t) data; bwr.read_size = 0; bwr.read_consumed = 0; bwr.read_buffer = 0; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); return res; }
|
提供功能:注册服务、添加服务
BBinder和BpBinder
1 2
| virtual BBinder* localBinder(); virtual BpBinder* remoteBinder();
|
BpBinder负责传输数据,BBinder负责接收数据和处理数据。