背景

本人使用的字体库是:https://github.com/InflationX/Calligraphy,这个库可以hook所有的TextView更换到我们需要的字体样式。

StackTrace:

2019-05-17 11:53:29.836 W/System.err: android.view.InflateException: Binary XML file line #32: Binary XML file line #32: Error inflating class TextView2019-05-17 11:53:29.836 W/System.err: Caused by: android.view.InflateException: Binary XML file line #32: Error inflating class TextView2019-05-17 11:53:29.841 W/System.err: Caused by: android.content.res.Resources$NotFoundException: Unable to find resource ID #0x20b017c2019-05-17 11:53:29.841 W/System.err:     at android.content.res.ResourcesImpl.getResourceEntryName(ResourcesImpl.java:291)2019-05-17 11:53:29.841 W/System.err:     at android.content.res.Resources.getResourceEntryName(Resources.java:2017)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.calligraphy3.Calligraphy.matchesResourceIdName(Calligraphy.java:94)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.calligraphy3.Calligraphy.isActionBarTitle(Calligraphy.java:57)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.calligraphy3.Calligraphy.getStyleForTextView(Calligraphy.java:33)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.calligraphy3.Calligraphy.onViewCreatedInternal(Calligraphy.java:139)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.calligraphy3.Calligraphy.onViewCreated(Calligraphy.java:117)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.calligraphy3.CalligraphyInterceptor.intercept(CalligraphyInterceptor.java:19)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.viewpump.internal.-InterceptorChain.proceed(-InterceptorChain.kt:30)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.viewpump.ViewPump.inflate(ViewPump.kt:36)2019-05-17 11:53:29.841 W/System.err:     at io.github.inflationx.viewpump.internal.-ViewPumpLayoutInflater$WrapperFactory2.onCreateView(-ViewPumpLayoutInflater.kt:350)2019-05-17 11:53:29.841 W/System.err:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:811)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:769)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.rInflate(LayoutInflater.java:902)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:863)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.rInflate(LayoutInflater.java:905)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:863)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.inflate(LayoutInflater.java:554)2019-05-17 11:53:29.842 W/System.err:     at io.github.inflationx.viewpump.internal.-ViewPumpLayoutInflater.inflate(-ViewPumpLayoutInflater.kt:53)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.inflate(LayoutInflater.java:461)2019-05-17 11:53:29.842 W/System.err:     at io.github.inflationx.viewpump.internal.-ViewPumpLayoutInflater.inflate(-ViewPumpLayoutInflater.kt:44)2019-05-17 11:53:29.842 W/System.err:     at android.view.LayoutInflater.inflate(LayoutInflater.java:383)2019-05-17 11:53:29.842 W/System.err:     at cJL.getView(PG:19)2019-05-17 11:53:29.842 W/System.err:     at android.widget.AbsListView.obtainView(AbsListView.java:3219)2019-05-17 11:53:29.842 W/System.err:     at android.widget.ListView.onMeasure(ListView.java:1326)2019-05-17 11:53:29.842 W/System.err:     at android.view.View.measure(View.java:24954)2019-05-17 11:53:29.842 W/System.err:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7134)2019-05-17 11:53:29.842 W/System.err:     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)2019-05-17 11:53:29.842 W/System.err:     at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)2019-05-17 11:53:29.842 W/System.err:     at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)2019-05-17 11:53:29.842 W/System.err:     at android.view.View.measure(View.java:24954)2019-05-17 11:53:29.842 W/System.err:     at cMB.d(PG:53)2019-05-17 11:53:29.843 W/System.err:     at cJO.a(PG:8)2019-05-17 11:53:29.843 W/System.err:     at cwX.(PG:11)2019-05-17 11:53:29.843 W/System.err:     at org.chromium.content.browser.input.SelectPopup.show(PG:40)2019-05-17 11:53:29.843 W/System.err:     at android.os.MessageQueue.nativePollOnce(Native Method)2019-05-17 11:53:29.843 W/System.err:     at android.os.MessageQueue.next(MessageQueue.java:326)2019-05-17 11:53:29.843 W/System.err:     at android.os.Looper.loop(Looper.java:181)2019-05-17 11:53:29.843 W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7072)2019-05-17 11:53:29.843 W/System.err:     at java.lang.reflect.Method.invoke(Native Method)2019-05-17 11:53:29.843 W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)2019-05-17 11:53:29.843 W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)2019-05-17 11:53:29.847 E/WifiConnectivityMonitor: msg.arg1 != mRssiFetchToken2019-05-17 11:53:29.854 A/chromium: [FATAL:jni_android.cc(249)] Please include Java exception stack in crash report2019-05-17 11:53:29.856 A/libc: Fatal signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0xe6735000 in tid 10822 (roid.production), pid 10822 (roid.production)2019-05-17 11:53:29.938 I/crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone2019-05-17 11:53:29.942 I//system/bin/tombstoned: received crash request for pid 108222019-05-17 11:53:29.944 I/crash_dump32: performing dump of process 10822 (target tid = 10822)2019-05-17 11:53:29.965 A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***2019-05-17 11:53:29.965 A/DEBUG: Build fingerprint: 'samsung/gta3xleea/gta3xl:9/PPR1.180610.011/T515XXU1ASCK:user/release-keys'2019-05-17 11:53:29.965 A/DEBUG: Revision: '4'2019-05-17 11:53:29.965 A/DEBUG: ABI: 'arm'2019-05-17 11:53:29.965 A/DEBUG: signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0xe67350002019-05-17 11:53:29.965 A/DEBUG: Abort message: '[FATAL:jni_android.cc(249)] Please include Java exception stack in crash report    '2019-05-17 11:53:29.965 A/DEBUG:     r0  00000000  r1  c88e12a0  r2  00000400  r3  000000002019-05-17 11:53:29.965 A/DEBUG:     r4  ffdc3108  r5  d0ee14d8  r6  e70683c8  r7  ffdc30ec2019-05-17 11:53:29.965 A/DEBUG:     r8  e706dd94  r9  ffdc3544  r10 ffdc3540  r11 ffdc353c2019-05-17 11:53:29.965 A/DEBUG:     ip  ffdc310c  sp  ffdc30d8  lr  cf8f32d1  pc  cf8f33ba2019-05-17 11:53:30.054 A/DEBUG: backtrace:2019-05-17 11:53:30.054 A/DEBUG:     #00 pc 023003ba  /data/app/com.android.chrome-1HS2RCE7TlSpdPbYl-VZLg==/base.apk (offset 0x1ee5000)

从上报来看,都是三星手机,而且都是Android 9手机,崩到Native Crash去了。

 

分析过程

一开始以为是oom问题引起的,(因为最近很多OOM上报)

带着疑问去寻找根源,打开用户的路径,找到两个用户分析:

我们根据用户的ui action,分析了一下,用户在崩溃之前,没有做图片的操作,看到内存也比较充足,

因此,我们可以推断跟oom没啥关系。

并且,我用其他三星手机测试过大图,并没有发现oom问题。

因此,oom的原因可以排除。

于是请教了WebView 内核开发的同学,给了一个文章,提供了一些思路。

可以得出以下这样的结论:

实际上在最上面可以看到一个jni报的异常,说明上面有java异常没有正确处理。事实上以上问题在使用系统webview的时候也同样会发生。

这里有很多人会产生这样一个误解:java发生异常肯定是崩在java里的,不会崩到native里。在大部分情况下这句话是正确的,但是在native通过jni调用java方法时就不正确了。

在jni调用java方法时,因为jni没有try...catch的机制,如果发生java异常,后续的代码不会停止,仍然会继续执行。而为了避免程序发生重大问题,在jni中一般会调用ExceptionCheck来检查java代码运行有没有发生异常。

如果发生了异常,可以调用ExceptionDescribe函数打印这个异常的堆栈信息,然后再调用ExceptionClear函数清除异常堆栈信息的缓冲区(如果不清除,后面调用ThrowNew抛出的异常堆栈信息会覆盖前面的异常信息),最后调用ThrowNew函数手动抛出一个java.lang.Exception异常。但是在JNI中抛出未捕获的异常与Java的异常处理机制不一样,在JNI中并不会立即终止本地方法的执行,而是继续执行后面的代码,这种情况下仍然有可能导致问题的产生,这种情况下就需要手动处理。所以大多数情况下,如果在jni中检测到发生了java异常没catch住,一般都会选择主动崩溃。

 

于是根据原始日志,应该就是15691这个线程崩了,报的是这个字体第三方库崩了;那就是字体库的问题了。

 

这种问题,线上可能不好太定位哪里出错了,也没找到复现路径,于是看看这个库有没有人去提到这个事情;

于是马上这个库的isues去看看,发现果然有人提到这个问题:

https://github.com/InflationX/Calligraphy/issues/30

产生的问题很类似,弹出一个popwindow,然后就会出现问题。

 

直接找关键源码

cpp的定义:

https://doss-gitlab.eidos.ic.i.u-tokyo.ac.jp/liujp-arch/chromium/blob/735d96ce1da80955647f0cb0389214a6f97962e9/content/browser/android/text_suggestion_host_android.h

 

Java层的调用:

https://chromium.googlesource.com/chromium/src/+/66.0.3359.158/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionHost.java?autodive=0%2F%2F%2F%2F%2F

 

 

 

可是,已经有人提了merge,但是一直没有合进去:(这??尴尬)

https://github.com/InflationX/Calligraphy/pull/31/commits/09eaf23cee3fe5be0b6687c600da79df3074cd59,导致3.1.12一直没发出去。。。

而我们使用自定义字体库的时候,刚好是10.9,没吃到这个螃蟹(10.23)。

 

|

 

 

根本原因

​context.getResources().getResourceEntryName(resId);​

 Caused by: android.content.res.Resources$NotFoundException: Unable to find resource ID #0x20b0031>

获取资源id它的名字 在三星 系统9手机有可能是空的。在其他手机测试未发现异常。

具体的原因,猜测是三星这个id在编译之后地址偏移或者没有了,深入的原因还需要更深入的看看。

 

为了证实最后的结论,我在输入的时候模拟出现三星的suggestion功能。操作步骤是,输入几个字母,点击空格,几个字母成为单词会有下划线,并且出现这个PopupWindow,然后再点击PopupWindow上面提示的单词。问题就会复现!

 

 

跟我们的错误堆栈完全吻合!!

 

思考 :

 使用别人的第三方库,确实存在着会有一些不可预知的问题。如何尽早的发现问题?

个人的感觉使用别人的第三方库首先要多思考稳定性问题,是否有一些场景没考虑到,可以通过查看issues和mr去多了解一下,并且在接入的时候,可以多做一些技术调研,是否有优化的地方。

 

更多相关文章

  1. Android理解Fragment生命周期,fragment和fragmentactivity解析
  2. Android(安卓)对话框(Dialog)大全 建立你自己的对话框 【转】
  3. android调用java的web service接口
  4. Android(安卓)View的scrollTo()、scrollBy() 和Scroller类总结
  5. android NDK开发 静态/动态注册 jni
  6. Android(安卓)WebView中无法用JS调用Java对象的问题
  7. 由一份 log 看 Binder
  8. 使用Android(安卓)studio3.6的java api方式调用opencv
  9. Android的Linux内核的电源管理:Early Suspend

随机推荐

  1. Android(安卓)屏蔽蓝牙连接时的首次配对
  2. 图解Android应用程序构建原理
  3. activity 的属性android:taskAffinity和a
  4. Android可循环显示图像的Android(安卓)Ga
  5. android基于XMPP的消息推送机制
  6. 基于Android的 拍照上传 程序开发
  7. Android中Handler,Looper,MessageQueue和Th
  8. Android与电脑局域网共享之:Samba Server
  9. Android软件如何进行推广?十种推广方式可
  10. [Android] 缓存机制