有坑!Android新版QQ獲取packageInfo引發(fā)異常崩潰

起因

最近從錯誤日志中檢查到一個異常崩潰:

 java.lang.RuntimeException: Package manager has died
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3151)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3261)
at android.app.ActivityThread.access$1000(ActivityThread.java:219)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1735)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6939)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.RuntimeException: Package manager has died
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:167)
at com.umeng.socialize.utils.DeviceConfig.isAppInstalled(DeviceConfig.java:46)
at com.umeng.socialize.sso.UMTencentSsoHandler.isClientInstalled(UMTencentSsoHandler.java:456)
at com.haodf.android.posttreatment.doctorhonnrreflect.fragment.UmengShareUtil.shareContentToQQZone(UmengShareUtil.java:220)
at com.haodf.android.basic.home.extension.AdDetailActivity.init(AdDetailActivity.java:74)
at com.haodf.android.base.activity.AbsBaseActivity.onCreate(AbsBaseActivity.java:116)
at android.app.Activity.performCreate(Activity.java:6609)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3104)
... 10 more
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:496)
at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:2222)
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:162)
... 18 more
java.lang.RuntimeException: Package manager has died
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:167)
at com.umeng.socialize.utils.DeviceConfig.isAppInstalled(DeviceConfig.java:46)
at com.umeng.socialize.sso.UMTencentSsoHandler.isClientInstalled(UMTencentSsoHandler.java:456)
at com.haodf.android.posttreatment.doctorhonnrreflect.fragment.UmengShareUtil.shareContentToQQZone(UmengShareUtil.java:220)
at com.haodf.android.basic.home.extension.AdDetailActivity.init(AdDetailActivity.java:74)
at com.haodf.android.base.activity.AbsBaseActivity.onCreate(AbsBaseActivity.java:116)
at android.app.Activity.performCreate(Activity.java:6609)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3104)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3261)
at android.app.ActivityThread.access$1000(ActivityThread.java:219)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1735)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6939)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:496)
at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:2222)
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:162)
... 18 more
android.os.TransactionTooLargeException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:496)
at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:2222)
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:162)
at com.umeng.socialize.utils.DeviceConfig.isAppInstalled(DeviceConfig.java:46)
at com.umeng.socialize.sso.UMTencentSsoHandler.isClientInstalled(UMTencentSsoHandler.java:456)
at com.haodf.android.posttreatment.doctorhonnrreflect.fragment.UmengShareUtil.shareContentToQQZone(UmengShareUtil.java:220)
at com.haodf.android.basic.home.extension.AdDetailActivity.init(AdDetailActivity.java:74)
at com.haodf.android.base.activity.AbsBaseActivity.onCreate(AbsBaseActivity.java:116)
at android.app.Activity.performCreate(Activity.java:6609)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3104)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3261)
at android.app.ActivityThread.access$1000(ActivityThread.java:219)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1735)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6939)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

分析

該異常由友盟SDK拋出,友盟SDK在進行QQ分享之前調(diào)用下方代碼判斷是否已安裝該應(yīng)用心铃。

    public static boolean isAppInstalled(String var0, Context var1) {
        if(var1 == null) {
            return false;
        } else {
            PackageManager var2 = var1.getPackageManager();
            boolean var3 = false;

            try {
                var2.getPackageInfo(var0, 1);
                var3 = true;
            } catch (NameNotFoundException var5) {
                var3 = false;
            }

            return var3;
        }
    }

在這段代碼中,var2.getPackageInfo(var0, 1);調(diào)用時可能引發(fā)java.lang.RuntimeException: Package manager has died這個異常挫剑。原因是目前版本的QQ(v6.6.9)PackageInfo中數(shù)據(jù)量太大了去扣,在部分手機上超出了Binder可傳遞的最大容量,進而導(dǎo)致PacakgeManager崩潰樊破。

驗證

我在三星S6 Android6.0.1這部手機上重現(xiàn)了這個崩潰愉棱。當我將QQ換為一個較早的版本后,上面檢測的這段代碼不會引起崩潰哲戚,因此驗證了我的推斷:近期QQ的更新使得PackageInfo增大引發(fā)這個異常奔滑。另外,這個崩潰不會在所有機型上出現(xiàn)顺少,也不是偶現(xiàn)朋其,只在部分機型上必現(xiàn)王浴。推測和系統(tǒng)層中對Binder傳遞數(shù)據(jù)最大容量的不同限制大小有關(guān)。

解決

如果是使用友盟分享SDK時發(fā)生的問題梅猿,請將SDK更新到Android 社會化組件SDK v6.2.3(2017-1-23)以上版本即可修復(fù)氓辣。

如果是自己寫的判斷方法報錯,繼續(xù)往下看袱蚓。
最直接的想法是catch住這個異常钞啸,這樣處理的確能夠避免引發(fā)崩潰,可以用來緊急解決崩潰的問題癞松。但是這樣做還是無法正常判斷QQ是否已經(jīng)安裝爽撒。
既然是PackageInfo過大那么我們可以嘗試改變getPackageInfo(var0, 1)它的第二個參數(shù)flag,使得該方法返回的對象容量減小响蓉。

    /**
     * Retrieve overall information about an application package that is
     * installed on the system.
     * <p>
     * Throws {@link NameNotFoundException} if a package with the given name can
     * not be found on the system.
     *
     * @param packageName The full name (i.e. com.google.apps.contacts) of the
     *            desired package.
     * @param flags Additional option flags. Use any combination of
     *            {@link #GET_ACTIVITIES}, {@link #GET_GIDS},
     *            {@link #GET_CONFIGURATIONS}, {@link #GET_INSTRUMENTATION},
     *            {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
     *            {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
     *            {@link #GET_SIGNATURES}, {@link #GET_UNINSTALLED_PACKAGES} to
     *            modify the data returned.
     * @return Returns a PackageInfo object containing information about the
     *         package. If flag GET_UNINSTALLED_PACKAGES is set and if the
     *         package is not found in the list of installed applications, the
     *         package information is retrieved from the list of uninstalled
     *         applications (which includes installed applications as well as
     *         applications with data directory i.e. applications which had been
     *         deleted with {@code DONT_DELETE_DATA} flag set).
     * @see #GET_ACTIVITIES
     * @see #GET_GIDS
     * @see #GET_CONFIGURATIONS
     * @see #GET_INSTRUMENTATION
     * @see #GET_PERMISSIONS
     * @see #GET_PROVIDERS
     * @see #GET_RECEIVERS
     * @see #GET_SERVICES
     * @see #GET_SIGNATURES
     * @see #GET_UNINSTALLED_PACKAGES
     */
    public abstract PackageInfo getPackageInfo(String packageName, int flags)
            throws NameNotFoundException;

在注釋中可以看到GET_SIGNATURES這個flag硕勿,它的作用是返回應(yīng)用的簽名,我們知道任何應(yīng)用都只有一個簽名枫甲,它的大小應(yīng)該是相對固定的源武。那么我們只需要改變參數(shù)flag的值即可在正確檢查是否安裝應(yīng)用的同時避免引發(fā)崩潰。

    public static boolean isAppInstalled(String var0, Context var1) {
        if(var1 == null) {
            return false;
        } else {
            PackageManager var2 = var1.getPackageManager();
            boolean var3 = false;

            try {
                var2.getPackageInfo(var0, PackageManager.GET_SIGNATURES);
                var3 = true;
            } catch (NameNotFoundException var5) {
                var3 = false;
            }

            return var3;
        }
    }

總結(jié)

雖然這次引發(fā)崩潰的是QQ想幻,但今后我們在應(yīng)用中獲取其它應(yīng)用的PackageInfo時都應(yīng)該注意這個問題粱栖,傳遞恰當?shù)膄lag避免同類問題的產(chǎn)生。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脏毯,一起剝皮案震驚了整個濱河市闹究,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌食店,老刑警劉巖渣淤,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吉嫩,居然都是意外死亡价认,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門自娩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來用踩,“玉大人,你說我怎么就攤上這事忙迁∑瓴剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵动漾,是天一觀的道長丁屎。 經(jīng)常有香客問我,道長旱眯,這世上最難降的妖魔是什么晨川? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任证九,我火速辦了婚禮,結(jié)果婚禮上共虑,老公的妹妹穿的比我還像新娘愧怜。我一直安慰自己,他們只是感情好妈拌,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布拥坛。 她就那樣靜靜地躺著,像睡著了一般尘分。 火紅的嫁衣襯著肌膚如雪猜惋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天培愁,我揣著相機與錄音著摔,去河邊找鬼。 笑死定续,一個胖子當著我的面吹牛谍咆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播私股,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼摹察,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了倡鲸?” 一聲冷哼從身側(cè)響起供嚎,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎峭状,沒想到半個月后查坪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡宁炫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了氮凝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羔巢。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖罩阵,靈堂內(nèi)的尸體忽然破棺而出竿秆,到底是詐尸還是另有隱情,我是刑警寧澤稿壁,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布幽钢,位于F島的核電站,受9級特大地震影響傅是,放射性物質(zhì)發(fā)生泄漏匪燕。R本人自食惡果不足惜蕾羊,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帽驯。 院中可真熱鬧龟再,春花似錦、人聲如沸尼变。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嫌术。三九已至哀澈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間度气,已是汗流浹背割按。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚯嫌,地道東北人哲虾。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像择示,于是被迫代替她去往敵國和親束凑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容