Android 5设备isGooglePlayServicesAvailable引发TransactionTooLargeException求助
我之前也碰到过这个棘手的问题——Android 5设备上,尤其是一加、索尼、Zuk这些机型,Google Play Services内部触发的可用性检查会因为TransactionTooLargeException导致Package Manager崩溃,而且完全是Google内部逻辑,我们根本碰不到那个过大的Parcel。下面是我整理的几个可行解决方案:
提前捕获异常并兜底处理
虽然你没显式调用检查逻辑,但可以在初始化Google相关API的外层加异常捕获,或者封装一个安全的检查方法,把RuntimeException和TransactionTooLargeException拦下来:public boolean isGooglePlayServicesSafeAvailable(Context context) { try { GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); int resultCode = apiAvailability.isGooglePlayServicesAvailable(context); return resultCode == ConnectionResult.SUCCESS; } catch (RuntimeException e) { // 专门处理PackageManager崩溃或Parcel过大的异常 if (e.getCause() instanceof TransactionTooLargeException) { // 直接返回"不可用",避免APP崩溃 return false; } // 其他异常正常抛出,不影响原有逻辑 throw e; } }之后所有依赖Google Play Services可用性判断的逻辑,都用这个封装方法替代;也可以在Application的全局异常处理器里,针对这个特定异常做兜底,不让APP直接崩溃。
延迟Google服务初始化时机
避免在APP启动阶段就触发Google Play Services的检查,把相关初始化延迟到用户需要用到对应功能的时候(比如用户点击地图、云同步按钮时),这样既减少了启动阶段的崩溃概率,也给系统留出更多时间处理Package Manager的事务。针对Android 5设备做特殊适配
因为这个问题集中出现在Android 5(API 21)及以下的特定机型,你可以通过系统版本判断,对这些设备跳过非核心的Google服务,或者用轻量化方案替代:if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) { // 针对Android 5及以下设备,禁用非必要的Google服务 disableNonCriticalGoogleServices(); } else { // 正常初始化Google Play Services initGoogleServices(); }引导用户清理Package Manager缓存
部分机型的问题是因为Package Manager缓存过大导致的,你可以在APP的帮助页面或者崩溃提示里,引导用户操作:设置 -> 应用 -> 全部应用 -> 找到"软件包安装程序"或"Package Manager" -> 清除缓存和数据,之后重启设备,能缓解这类问题。
原始崩溃日志
Fatal Exception: java.lang.RuntimeException: Package manager has died at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:112) at com.google.android.gms.common.zzo.isGooglePlayServicesAvailable(Unknown Source) at com.google.android.gms.common.zze.isGooglePlayServicesAvailable(Unknown Source) at com.google.android.gms.common.GoogleApiAvailability.getInstance(Unknown Source) at com.google.android.gms.common.api.internal.zzbr.connect(Unknown Source) at com.google.android.gms.common.api.internal.zzbp.zzb(Unknown Source) at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:135) at android.os.HandlerThread.run(HandlerThread.java:61) Caused by android.os.TransactionTooLargeException at android.os.BinderProxy.transactNative(Binder.java) at android.os.BinderProxy.transact(Binder.java:496) at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:1876) at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:107) at com.google.android.gms.common.zzo.isGooglePlayServicesAvailable(Unknown Source) at com.google.android.gms.common.zze.isGooglePlayServicesAvailable(Unknown Source) at com.google.android.gms.common.GoogleApiAvailability.getInstance(Unknown Source) at com.google.android.gms.common.api.internal.zzbr.connect(Unknown Source) at com.google.android.gms.common.api.internal.zzbp.zzb(Unknown Source) at com.google.android.gms.common.api.internal.zzbp.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:135) at android.os.HandlerThread.run(HandlerThread.java:61)
内容的提问来源于stack exchange,提问作者Graham Smith

