需求背景
项目中有个需求是这样的,在主进程Activity 中选择或者编辑一张背景图产生一个bitmap 对象,要传递给 B进程(推流进程)作为推流引擎的背景图,这个bitmap 有可能比较大,因为要尽量保证清晰度,所以这个bitmap还有可能比较大,所以必然会涉及到跨进程传输大型bitmap 的问题。
有哪些方案
跨进程传递大图,我们能想到哪些方案呢?
文件写入磁盘
最容易想到的方案就是先给图片保存到文件,给路径跨进程传过去,对方再从文件给图片decode出来,这个方案可行的,但是不够高效。
走系统IPC方式
另一种方案就是通过跨进程通信的方式,就是不走文件,直接走内存,这个肯定会快不少。跨进程通信有哪些方式呢?
首先Binder性能是可以,用起来也方便,但是有大小的限制,传的数据量大了就会抛异常。Socket或者管道性能不太好,涉及到至少两次拷贝。共享内存性能还不错,可以考虑,关键看怎么实现。
我们来看,通过Binder传图,一个是通过Intent传图,还一个可以通过Binder调用传图。这两个不是一回事?你可能会有疑问,那么我们具体来看下这两种有什么区别。
直接Intent传递
先看常规Intent传图,我们塞进去一个超大的图。
这个
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("bitmap", mBitmap);
startActivity(intent);
bitmap 是一张很大的图片。
正常传大图 抛出如下异常
2019-07-27 20:40:38.981 19460-19460/io.github.brijoe.ipcbigbitmapdemo E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.github.brijoe.ipcbigbitmapdemo, PID: 19460
...
Caused by: android.os.TransactionTooLargeException: data parcel size 14293996 bytes
...
那我们看下系统对这个异常是怎么解释的
理解TransactionTooLargeException
The Binder transaction failed because it was too large.
During a remote procedure call, the arguments and the return value of the call are transferred as Parcel objects stored in the Binder transaction buffer. If the arguments or the return value are too large to fit in the transaction buffer, then the call will fail and TransactionTooLargeException will be thrown.
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
There are two possible outcomes when a remote procedure call throws TransactionTooLa