Class类版本差异引起的闪退

在这里插入图片描述
详细日志比较多,便列举在了最下方,有需要可以查看

此代码在 Android 10、Android 11 运行没问题,哈哈哈哈,可以发版本了

唉!正好覆盖测试没有覆盖 Android 9、8、7、6 等版本的设备,蹭蹭蹭测试验收通过之后出包提审

坏了!坏了!提审没有通过

被拒原因是启动出现闪退,闪退的机型是 EMUI5.1.0(P10)Android 7

不是测试通过了么,怎么启动闪退

竟然不可以运行,为什么呢?

版本测试覆盖不全,真的难

常规操作,连接 adb 查看日志吧


两个不同原因描述的 Caused by :

以往的崩溃不止只有一个原因吗?不是对应一个 Caused by :

关键日志 1

Caused by: java.lang.RuntimeException: Failed to call observer method

对于这个错误看到很对描述是:对于外部未捕获的异常为此抛出异常

第一次读这句话我也感觉有点绕口,可以这么理解,举个栗子:

1、被 @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) 观察的 onCreate() 方法,如

private Activity activity = this;

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate(LifecycleOwner source) {
	eatFood();
}

private void eatFood(){
	String typeName = activity.getClass().getTypeName();
	Log.d("TAG", "onResume: typeName = "+ typeName);
}

2、如果 activity.getClass() 中没有方法 getTypeName() 方法可以调用,会不会报错,肯定报错啊!

3、重点是 String typeName = activity.getClass().getTypeName(); 这条语句你没有 try { } catch(Exception e ){ } 捕获异常,因为你、我可能不知道这里是否存在异常需要捕获。

如果eatFood()方法中抛出了异常 java.lang.NoSuchMethodError: No virtual method getTypeName()或者是其他异常,并且你没有捕获异常,那么在此之前Lifecycle会先抛出 java.lang.RuntimeException: Failed to call observer method 异常。

正是因为 eatFood() 是在 OnLifecycleEvent 观察生命周期回调方法中执行,所以这里出现两个不同描述的 Cause by :


一开始我还默默地看代码以为问题根源在 OnLifecycleEvent ,果不其然方向都错了。

理解了上面的描述才恍然大悟,接下来排查为重点关注第二个 Cause by :,也就是下面的关键日志。

关键日志 2

Caused by: java.lang.NoSuchMethodError: No virtual method getTypeName()Ljava/lang/String; in class Ljava/lang/Class; or its super classes

getTypeName() 哪里调用了这个方法?

工程全局搜索,有两个地方使用到:

位置一:

NetworkInfo info = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

String type = info.getTypeName().toLowerCase();

进一步跳入源码,看到 @Deprecated,曾一度对此产生怀疑,怀疑在某些较低版本的 Android 系统上已经不支持使用 NetworkInfo ,最终说明我的怀疑是没有依据的、无效的。

@Deprecated
public class NetworkInfo implements Parcelable {

	@Deprecated
	public String getTypeName() {
	    synchronized (this) {
	        return mTypeName;
	    }
	}
}

No virtual method getTypeName() 难道说复现机型(Android 7)NetworkInfo 类中没有此方法

那翻一下对应的 android.jar 源码看看【Android 7 对应的是 android platform API 24】,方法存在啊!不应该会出现方法调用错误异常。那么接着看下一条日志吧
在这里插入图片描述


位置二:

都是方法调用,排查思路其实还是一样的,看看不同版本之间getTypeName()方法是否有什么不同。

String typeName = activity.getClass().getTypeName();

先看看闪退设备 Android 7 对应 android platform API 24 的 android.jar,很遗憾,没有看到 getTypeName() 方法
在这里插入图片描述

再看看不闪设备 Android 对应 android platform API 24 的 android.jar,很惊喜(这不,问题找到了),有看到了 getTypeName() 方法
在这里插入图片描述

所以呢?我项目中是使用了activity.getClass().getTypeName(),并且没有做版本判断,那么在 Android7 运行找不到方法抛出异常便闪退了。

解决方法可以是做版本兼容判断,但是你要明确从那个版本开始新增的这个方法;如果这个字段意义不大注释不使用便可。

竟然可以运行,为什么呢?


详细日志

ii1iIII1 样式的是按照一定规则进行混淆

2022-05-17 15:31:54.323 20284-20284/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: 【包名】, PID: 20284
    java.lang.Error: FATAL EXCEPTION [main]
    Unity version     : 2019.4.36f1c1
    Device model      : HUAWEI VTR-AL00
    Device fingerprint: HUAWEI/VTR-AL00/HWVTR:7.0/HUAWEIVTR-AL00/C00B172:user/release-keys
    
    Caused by: java.lang.RuntimeException: Unable to resume activity {【包名】/org.xqq.w.AppActivity}: java.lang.RuntimeException: Failed to call observer method
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3636)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3676)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2876)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6577)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: java.lang.RuntimeException: Failed to call observer method
        at androidx.lifecycle.iIIIiIII$iIIIiIII.iiiiIiI1(ClassesInfoCache.java:6)
        at androidx.lifecycle.iIIIiIII$iiiiIiI1.iIIIiIII(ClassesInfoCache.java:2)
        at androidx.lifecycle.iIIIiIII$iiiiIiI1.iiiiIiI1(ClassesInfoCache.java:1)
        at androidx.lifecycle.ReflectiveGenericLifecycleObserver.iiiiIiI1(ReflectiveGenericLifecycleObserver.java:1)
        at androidx.lifecycle.i11iIIIi$iiiiIiI1.iiiiIiI1(LifecycleRegistry.java:3)
        at androidx.lifecycle.i11iIIIi.iIIiIIiI(LifecycleRegistry.java:10)
        at androidx.lifecycle.i11iIIIi.i1IIIiii(LifecycleRegistry.java:9)
        at androidx.lifecycle.i11iIIIi.iIiIi111(LifecycleRegistry.java:5)
        at androidx.lifecycle.i11iIIIi.I111I111(LifecycleRegistry.java:2)
        at com.gg.r.f.bOhH.I111I111(LifecycleManager.java:1)
        at com.gg.v.bh.ULXt.onResume(UniWbActivity.java:3)
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1279)
        at android.app.Activity.performResume(Activity.java:7017)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3611)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3676) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2876) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:156) 
        at android.app.ActivityThread.main(ActivityThread.java:6577) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832) 
     Caused by: java.lang.NoSuchMethodError: No virtual method getTypeName()Ljava/lang/String; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /system/framework/core-oj.jar)
        at 【路径】.pay.huawei.agents.HuaweiAgent.init(HuaweiAgent.java:6)
        at 【路径】.pay.manager.ii1iIII1.iIi11iI()
        at 【路径】.pay.manager.ii1iIII1.iIii1Ii()
        at 【路径】.pay.manager.ii1iIII1.activityOnCreate()
        at com.gg.p.tly.kVFR.activityOnCreate()
        at I111I111.ii1IIii.iIIIiIII.iIIIiIII.iIIiIIiI.ii1iIiIi.i1IIIiii()
        at I111I111.ii1IIii.iIIIiIII.iIIIiIII.iIIiIIiI.ii1iIiIi.i1()
        at 【路径】.game.GameManager.iIiIIii(GameManager.java:18)
        at 【路径】.game.GameManager.onResume(GameManager.java:2)
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.lifecycle.iIIIiIII$iIIIiIII.iiiiIiI1(ClassesInfoCache.java:3)
        at androidx.lifecycle.iIIIiIII$iiiiIiI1.iIIIiIII(ClassesInfoCache.java:2) 
        at androidx.lifecycle.iIIIiIII$iiiiIiI1.iiiiIiI1(ClassesInfoCache.java:1) 
        at androidx.lifecycle.ReflectiveGenericLifecycleObserver.iiiiIiI1(ReflectiveGenericLifecycleObserver.java:1) 
        at androidx.lifecycle.i11iIIIi$iiiiIiI1.iiiiIiI1(LifecycleRegistry.java:3) 
        at androidx.lifecycle.i11iIIIi.iIIiIIiI(LifecycleRegistry.java:10) 
        at androidx.lifecycle.i11iIIIi.i1IIIiii(LifecycleRegistry.java:9) 
        at androidx.lifecycle.i11iIIIi.iIiIi111(LifecycleRegistry.java:5) 
        at androidx.lifecycle.i11iIIIi.I111I111(LifecycleRegistry.java:2) 
        at com.gg.r.f.bOhH.I111I111(LifecycleManager.java:1) 
        at com.gg.v.bh.ULXt.onResume(UniWbActivity.java:3) 
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1279) 
        at android.app.Activity.performResume(Activity.java:7017) 
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3611) 
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3676) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2876) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:156) 
        at android.app.ActivityThread.main(ActivityThread.java:6577) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

Android 版本 & API

在这里插入图片描述

Android studio 下载 SDK Platform

在这里插入图片描述
回顾一下:
其实输出日志还是很清晰的,在 init 方法里发生方法调用异常,接着跟随 getTypeName() 排查;
主要一点是能够进一步排查不同版本的 Class 类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值