03-12 14:50:12.353: E/JavaBinder(16740): !!! FAILED BINDER TRANSACTION !!!
xxxRecorder 運行40多分鍾,崩潰,捕獲日志
03-12 14:50:12.353: E/JavaBinder(16740): !!! FAILED BINDER TRANSACTION !!!
原因:
Intent傳遞過大的值(Bitmap)
通過Intent傳送數據時,圖片的size不能超過40k
android aidl 進程間通信需要注意的地方(android.os.TransactionTooLargeException)
轉http://blog.sina.com.cn/s/blog_4e1e357d0102wau9.html
1.bus工程實現通過service實現aidl實體類
2.actor工程通過發起bindservice,根據action去啟動遠程(跨進程的)bus上的aidl。
那么問題來了,我們知道,linux系統進程間通信,各個進程間資源是隔離的,兩個進程間需要通信,就要把msg轉換成底層os系統能夠識別的數據單元,在Android里面的方案是aidl+parcelbal的序列化。
為了模擬和測試aidl的性能問題,我做了個簡單實驗,在Android中,進程間通信通過binder實現,bind是通信的數據載體,當序列化后的數據單元過大時,就會出問題,報出android.os.TransactionTooLargeException。
官方文檔里有說明,最大通常限制為1M.也就是說如果大於1M數據的話,就應該分開傳。理論上說,應該都是對象和字符串類型的數據為主,只要不是大圖片實體等問題,一般應該夠用。
我這邊做了一個測試,序列化傳送了450k的String被序列化 后的數據,耗時使用了33秒的時間。
try {
StringBuilder sb = new StringBuilder();
for(int i = 0;i< 30;i++){ sb.append(new String (stringMsg)); } System.out.println( "actor time start :" + System.currentTimeMillis()); binder.sendMsg("msg from actor : " + sb.toString()); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } ------ public static BusCore coreBinder = new BusCore.Stub() { @Override public void sendMsg(String msg) throws RemoteException { Log.d("", " RemoteBusCoreService msg:" + msg); System.out.println("buscore time end :" + System.currentTimeMillis()); } };
對於遠程服務,必須調用 bindService()方法,而不是 startService()方法。
今天剛好是在做框架性 實現方案測試時,稍微檢測了下個,mark下。