面试官提了一个问题,跨进程传递大图,你能想到哪些方案呢?
我们来看看 A、B和 C 三位同学的表现如何吧
A同学自认为无所不知,水平已达应用开发天花板,目前月薪 10k
「面试官」:如何跨进程传递大图
A:很简单,把图片存到 SD 卡,然后把路径传过去,在别的进程读出来这不就完事了嘛。
面试官:这个需要文件操作,效率不行,有别的方法吗?
A:Bitmap 实现了 Parcelable 接口,可以通过 Intent.putExtra(String name, Parcelable value) 方法直接放 Intent 里面传递。
面试官:那这个方法有什么缺点?
A:Bitmap 太大就会抛异常,所以我更喜欢传路径
面试官:为什么会抛异常?
A:…
面试官:好的,回去等通知吧
B同学业余时间经常打游戏、追剧、熬夜,目前月薪 15k
面试官:Intent 直接传 Bitmap 会有什么问题?
B:Bitmap 太大会抛 TransactionTooLargeException 异常,原因是:底层判断只要 Binder Transaction 失败,且 Intent 的数据大于 200k 就会抛这个异常了。(见:android_util_Binder.cpp 文件 signalExceptionForError 方法)
面试官:为什么 Intent 传值会有大小限制。
B:应用进程在启动 Binder 机制时会映射一块 1M 大小的内存,所有正在进行的 Binder 事务共享这 1M 的缓冲区。当使用 Intent 进行 IPC 时申请的缓存超过 1M - 其他事务占用的内存时,就会申请失败抛 TransactionTooLargeException 异常了。(哼,不会像上次一样答不出来了。见:“谈谈你对 binder 的理解?”)
面试官:如何绕开这个限制呢?
B:通过 AIDL 使用 Binder 进行 IPC 就不受这个限制,具体代码如下:
Bundle bundle = new Bundle();
bundle.putBinder("binder", new IRemoteGetBitmap.Stub() {
@Override
public Bitmap getBitMap() throws RemoteException {
return mBitmap;
}
});
intent.putExtras