1. 程式人生 > >【轉載】雙微信分享發生TransactionTooLargeException 異常記錄

【轉載】雙微信分享發生TransactionTooLargeException 異常記錄

原博地址: https://blog.csdn.net/xiaolli/article/details/60577331 博主@程立001
前提條件:
1. 開啟雙應用(設定-》雙應用)
2. 安裝微信。
復現步驟:
1. 用相機拍一張6M左右的照片並儲存到手機。
2. 進入相簿,開啟這張6M左右的照片後選擇分享-》朋友。
實際結果:
2. 介面閃一下後,無法彈出微信賬號選擇介面。
期望結果:
2. 能夠成功彈出微信賬號(主號,小號)選擇介面。
備註:
1. 5M以內的照片分享時能夠成功彈出微信賬號(主號,小號)選擇介面。

android app開發者臨時解決方案

對於android app開發來說,系統底層也不是自己能改的,我的臨時解決方案是,在微信分享圖片的時候,把圖片 壓縮大小到250k以內(原圖+縮圖),這樣 clone 後,就不會超過500k的資料限制了

堆疊為:
02-28 11:03:50.470 1297 2644 E JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 597856)
02-28 11:03:50.471 1297 2644 W ActivityManager: Exception when starting activity android/com...app.***MutiWechatActivity
02-28 11:03:50.471 1297 2644 W ActivityManager: android.os.TransactionTooLargeException: data parcel size 597856 bytes
02-28 11:03:50.471 1297 2644 W ActivityManager: at android.os.BinderProxy.transactNative(Native Method)
02-28 11:03:50.471 1297 2644 W ActivityManager: at android.os.BinderProxy.transact(Binder.java:503)
02-28 11:03:50.471 1297 2644 W ActivityManager: at android.app.ApplicationThreadProxy.scheduleLaunchActivity(ApplicationThreadNative.java:846)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1384)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1493)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2444)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1894)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStackSupervisor.resumeTopActivitiesLocked(ActivityStackSupervisor.java:3156)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1388)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1160)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:7463)
02-28 11:03:50.471 1297 2644 W ActivityManager: at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:539)
02-28 11:03:50.471 1297 2644 W ActivityManager: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2711)
02-28 11:03:50.471 1297 2644 W ActivityManager: at android.os.Binder.execTransact(Binder.java:453)

通過 dumpsys activity top 獲知:
分享介面為:android/com.android.internal.app.ChooserActivity
分享的雙微信介面為:android/com...app.***MutiWechatActivity

在 core/jni/android_util_Binder.cpp 的android_os_BinderProxy_transact 方法中新增log:
在傳輸之前將要傳輸的值的大小打印出來 @1
正常傳輸圖片的大小
02-23 15:11:21.623 1310 2641 E JavaBinder: data size is 59832 Java code calling transact on 0x7f6d6af1a0 in Java object 0x7f6c869d74 with code 7
異常的大小
02-23 15:15:38.073 1310 2751 E JavaBinder: data size is 597856 Java code calling transact on 0x7f6d6af1a0 in Java object 0x7f6bd64d74 with code 7
差別太大了。

懷疑是上層傳輸時 有問題:
ChooserActivity 所處的程序為android:ui, 使用jdb 大發,除錯android:ui 程序 在傳輸時加斷點:
stop in android.app.ActivityManagerProxy:2743 @2

正常情況下bindler傳輸資料大小:
data.dataSize() = 632
異常狀況下:
data.dataSize() = 584

對圖片應該使用的是路徑的傳輸方式,兩處相差不大,並且傳輸的資料並不大,不應該會造成 TransactionTooLargeException 異常啊,那為啥到對端,就變成 一個比較大,一個特別大:
??????

使用最笨的方法,在andorid_os_Parcel.cpp 類的各個方法中,新增類似此類判斷程式碼:
#include <utils/CallStack.h>

Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
size_t begin = parcel->dataSize();

size_t size = parcel->dataSize() - begin;
if(size > 5000){
ALOGE(“method name %zu parcel is %p”, parcel->dataSize(), parcel);

CallStack stack(LOG_TAG);
jclass throwable_class = env->FindClass(“java/lang/Throwable”);
jmethodID throwable_init = env->GetMethodID(throwable_class, “”, “(Ljava/lang/String;)V”);
jobject throwable_obj = env->NewObject(throwable_class, throwable_init, env->NewStringUTF(“hecheng”));

jmethodID throwable_mid = env->GetMethodID(throwable_class, “printStackTrace”, “()V”);
env->CallVoidMethod(throwable_obj, throwable_mid);
}

獲取異常的log:
02-28 12:15:13.297 1312 2598 E Parcel : android_os_Parcel_appendFrom thisParcel begin size 608, otherParcel size 297736, otherParcel end size is 298344, thisParcel is 0x7f8b528c20, otherParcel is 0x7f8b5281a0
02-28 12:15:13.298 1312 2598 E Parcel : android_os_Parcel_appendFrom thisParcel begin size 298664, otherParcel size 297736, otherParcel end size is 596400, thisParcel is 0x7f8b528c20, otherParcel is 0x7f82d0e3a0
02-28 12:15:13.298 1312 2598 E JavaBinder: data size is 597856 Java code calling transact on 0x7f6e8bd0e0 in Java object 0x7f6e0f7d74 with code 7
02-28 12:15:13.298 1312 2598 E JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 597856)

那麼是說明上層有使用者呼叫 android_os_Parcel_appendFrom — 往parcel中新增大資料,檢視上下文堆疊:
28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.nativeAppendFrom(Native Method)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.appendFrom(Parcel.java:453)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1317)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Bundle.writeToParcel(Bundle.java:1079)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.writeBundle(Parcel.java:711)
02-28 13:42:53.597 1332 2708 W System.err: at android.content.Intent.writeToParcel(Intent.java:8094)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.writeParcelable(Parcel.java:1437)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.writeValue(Parcel.java:1343)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Bundle.writeToParcel(Bundle.java:1079)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Parcel.writeBundle(Parcel.java:711)
02-28 13:42:53.597 1332 2708 W System.err: at android.content.Intent.writeToParcel(Intent.java:8094)
02-28 13:42:53.597 1332 2708 W System.err: at android.app.ApplicationThreadProxy.scheduleLaunchActivity(ApplicationThreadNative.java:819)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1384)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1493)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2444)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1894)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStackSupervisor.resumeTopActivitiesLocked(ActivityStackSupervisor.java:3156)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1388)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1160)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:7463)
02-28 13:42:53.597 1332 2708 W System.err: at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:539)
02-28 13:42:53.597 1332 2708 W System.err: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2711)
02-28 13:42:53.597 1332 2708 W System.err: at android.os.Binder.execTransact(Binder.java:453)
其實就是 ams 將,傳過來的 intent,通過呼叫Intent.writeToParcel 方法傳入底層,用於啟動***MutiWechatActivity 頁面啊。

但是從上面可知,傳過來的時候,intent 其實並不大啊,在仔細檢視上下文log:
02-28 14:06:41.528 6356 6356 W Intent_hecheng: writeBundle Parcel size: 298068
此處向binder 寫入的值較大,比較可疑,其程序名為:com.**.share,
從名字上看,應該也和分享有關啊,再次復現了一邊流程發現:
android/com.android.internal.app.ChooserActivity
|
com..share/com..share.LaunchWeChatShareActivity //此介面,只出現一瞬間
|
android/com...app.***MutiWechatActivity
因為LaunchWeChatShareActivity 只出現一瞬間,且用眼睛注意不到此介面,所以一直忽略此介面,
由此可以有一個合理的推測:
ChooserActivity 將圖片路徑存入 intent
LaunchWeChatShareActivity 取出圖片,將圖片放入intent
***MutiWechatActivity intent 過大,發生問題。
聯絡com.**.share 被告知:
1、其實根據手機螢幕解析度,去解析圖片的,本機的解析度較高(2k),所以解析圖片較大,
2、對比機,解析度較小,所以沒有問題,
3、且不啟動雙微信,沒有問題,請先排查雙微信問題.

好吧,為啥啟動雙微信會發生問題呢?
排查雙微信的程式碼,在ams 裡面發現:

如果開啟雙微信,在ams裡面,會將傳入的 intent,clone 出來一份,並且存入一個共同的intent 中,
就相當於,雙微信中,要傳輸的資料是 傳過來的二倍。

以原本的intent 為藍本,建立雙微信 的intent,
Intent _intent = new Intent(intent);
Intent _intentClone = new Intent(intent);

_intent.addCategory(INTENT_SHARE_CLONE);
_intentClone.addCategory(INTENT_CLONE);
_intentClone.addCategory(SHARE_CLONE);

建立雙微信要傳輸的 intent
Intent _intentDouble = new Intent();
_intentDouble.addFlags( Intent.FLAG_ACTIVITY_MULTIPLE_TASK |Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
_intentDouble.setClassName(“android”, “com...app.***MutiWechatActivity”);
Bundle mBundle = new Bundle();

將兩個微信的 intent,存入_intentDouble 中
mBundle.putParcelable(“intent”, _intent);
mBundle.putParcelable(“intent_Clone”, _intentClone);
_intentDouble.putExtras(mBundle);

本身LaunchWeChatShareActivity 傳過來的intent 就已經很大了,因為開啟了雙微信,要傳輸的資料擴大了兩倍,資料變得更大了,所以發生了oom。

解決方案:
在ams中intent,僅傳輸 原本的intent
在***MutiWechatActivity 端,進行double create操作

備註:
@1、傳輸值的大小data->dataSize(),返回的是 size_t 型別的格式,需要使用 zu% 列印

@2、通過step 、step up 與原始碼一步步確認,找到對應行數的

@3、在使用jdb 大法,在啟動 Activity頁面時,加斷點:
jdb stop in android.app.ActivityManagerProxy.startActivity

相關推薦

轉載分享發生TransactionTooLargeException 異常記錄

原博地址: https://blog.csdn.net/xiaolli/article/details/60577331 博主@程立001 前提條件: 1. 開啟雙應用(設定-》雙應用) 2. 安裝微信。 復現步驟: 1. 用相機拍一張6M左右的照片

原創配置伺服器與內網穿透--轉載請註明出處

微信公眾號開發 在進行學習微信公眾號開發時,首先我們需要做好一些必須的準備。 1.具有一個自己的公眾號平臺,方便進行學習。 2.在網上找一款內網穿透器,進行內網穿透,接入微信開發。 3.有一個已經搭建好的Web專案。 1.申請微信公眾號 進行微信公眾號申請時,在下方地址進

VueVueJS-SDK分享(系列二)

Vue中使用微信JS-SDK,配置分享 這是微信系列的第二篇,這裡講會講到微信SDK分享的運用(分享都會了,其他的API不就一通百通了嗎) 1:微信公眾平臺配置好域名 2:專案引入微信js-sdk 這裡我需要用到微信js-sdk的.js檔案,匯入方式: 下

ZT上有哪些高情商的說話方式 | M周刊(聽語音需要60秒,看文字只需10秒)

con 復雜 直接 對不起 評論 關系 專註 應該 知識 https://baijiahao.baidu.com/s?id=1590547145580792217&wfr=spider&for=pc https://yuedu.baidu.com/hybri

bug關於ios展示頁面的url和實際url不一致的問題

如題描述。 使用者開啟的頁面url和實際url不一致,假如展示的頁面是www.baidu.com.,微信端複製連結地址,出來的是www.163.com。 當然實際專案中出現的只是路由不一樣,域名是相同的。 由於這樣的原因,導致了頁面上的二維碼,識別不出來。就是長按沒有識別二維碼的選項。

Android搶紅包助手的實現(程式碼整理)

實現原理   通過利用AccessibilityService輔助服務,監測螢幕內容,如監聽狀態列的資訊,螢幕跳轉等,以此來實現自動拆紅包的功能。關於AccessibilityService輔助服務,可以自行百度瞭解更多。 程式碼基礎: 1.首先宣告一個RedPac

VueVue授權(系列一)

最近算是把微信授權,sdk,接觸了一邊了,所以準備寫一個系列; 微信授權 微信SDK的使用,例如分享等功能 小程式授權 小程式微信支付 小程式模板訊息 不要問我為什麼後面是小程式微信支付,小程式模板

專欄 - 基於公眾號的公益眾籌專案開發

基於微信公眾號的公益眾籌專案開發 筆者結合專案逐步講解微信公眾號開發,微信Api和JSSDK使用,多公眾號支援、微信支付、發紅包。涉及SpringMVC、MyBatise、AJAX跨域,Redis、MySql、Angalarjs+

迎接winphone 5.0 版本的IE10樣式相容

微信 Android 5.1 和 iPhone 5.1 已正式釋出了,據說本12月底,微信將推出 Winphone 5.0版本,全面支援微信支付,它繫結 IE10 瀏覽器,那麼做微信公眾號的 H5 頁面,除了做好 webkit 相容外,IE10 的相容也是必不可少的。 曾經寫過《常見CSS3屬性對ios

機智Android 6.2以上版本 轉移聊天記錄到ios,當前Wi-Fi環境複雜,無法傳輸 問題

問題描述 直接看解決方案,不想聽來龍去脈? 請點傳送門 買了個iPhone,想把以前Android上微信的聊天記錄轉移過來,於是乎,想到了幾個辦法: - 電腦備份,然後恢復到iPhone -

轉載NIPS 2017 線上分享第一期:新型強化學習演算法 ACKTR

上週我們釋出了《攻略 | 雖然票早已被搶光,你可以從機器之心關注 NIPS 2017》,在 NIPS 2017 正式開始前,我們將選出數篇優質論文,邀請論文作者來做線上分享,聊聊理論、技術和研究方法。11 月 8 日,第一期分享已經結束。週三晚上,多倫多大學三年級博士生 Yu

180929仿飛機大戰遊戲原始碼

進去到21世紀,由於科技的進步,各國空軍得到空前的大力發展,某一天終於因為某種利益而發生不可避免的空中侵略,戰爭由此拉開,作為守護自己國家的領空的飛翔員,不得不面臨隨時而來的各種飛機! 遊戲比較容易上手

轉載數據庫解密算法

fread ota total windows.h fopen roi openss herf %d #include "stdafx.h" #include <Windows.h> #include <openssl/rand.h> #inclu

轉載小程式-開發入門(一)

微信小程式已經火了一段時間了,之前一直也在關注,就這半年的發展來看,相對原生APP大部分公司還是不願意將主營業務放到微信平臺上,以免受制於騰訊,不過就小程式的應用場景(用完即走和二維碼分發等)還是很值得我們學習的,技術上面如果瞭解React的話,會發現他們在元件化上面有很多雷同之處。說白了,小程式就是基於微信

轉載Python 騷操作:遠端控制電腦

轉自Python中文社群 https://mp.weixin.qq.com/s/KPBNKLYvPgJqoUsWR6zBxw 今天帶給大家一個非常有意思的 python 程式,基於 itchat 實現微信控制電腦。你可以通過在微信傳送命令,來拍攝當前電腦的使用者,然後圖片會發送到你的微信上

騰訊Bugly乾貨分享打造“小程式”元件化開發框架

作者:Gcaufy 導語 Bugly 之前發了一篇關於微信小程式的開發經驗分享(點選閱讀),小夥伴們在公眾賬號後臺問了很多關於小程式開發方面的問題,精神哥在查閱相關內容的時候,發現了龔澄同學自己寫了一個小程式開發框架,真的怒贊,趕緊安利給大家

轉載Ubuntu 16.04 WINE 企業

注:本文為轉載,感謝原著作者的專業和詳細說明,解決了在ubuntu下使用企業問題的基本問題。請移步原連結或者本轉載頁面直接瀏覽。 本文只供備忘和交流,如有侵權請聯絡,隨即刪除,謝謝! 以下為轉載正文: Ubuntu 16.04 WINE 企業微信

分享(配置+開發)簡單流程只要配置的引數沒問題,就easy

首先網上查資料,沒有和配置結合,踩了坑(又不愛看官方文件,文字太多一堆口水話)。。。。。整理下自己完整的步驟1、公眾號【基本配置】裡面的【伺服器配置】(下面必須要空降方法,不然配置驗證通不過)一、首先專案匯入公眾號的jar包<!-- 微信公眾號 --> <d

ionic App問題總結系列ionic 朋友圈分享

前言 做完之後才發現實現ionic微信朋友圈、朋友分享並不難。只要按照著外掛的文件來就行。但是在剛接觸的時候依然是存在疑惑,還是寫點記錄總結下吧(本文是在開發Android App的環境下產生的)。 整個流程大致是下面三步: 微信開放平臺申請應用獲取ap

問題分享測試環境分享

signature 開啟 簽名 ges ref Once 測試的 title del 【問題】:在測試環境中,微信分享分享給好友的鏈接是當前頁面的鏈接,期望為接口返回的特定鏈接。 【解決】: 在測試反饋給我這個問題的時候,我先去正式環境看了一下