android - WebView.draw(canvas) 有时会在某些设备上的 Android Lollipop 5.0+ 中崩溃 - 致命信号 11 (SIGSEGV)

标签 android android-ndk android-webview android-canvas android-5.0-lollipop

我有一段代码在 UI 线程上运行,它要求 RelativeLayoutWebView 绘制到 Canvas 上:

someRelativeLayoutContainingWebView.draw(canvas);

这一行在某些 Android Lollipop 5.0 设备(Nexus 4、Nexus 5)上会崩溃,但在其他设备(Nexus 7)上可以正常工作。崩溃日志显示以下内容:

--------- beginning of crash
F/libc    (20829): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x8d68fc68 in tid 21178 (Thread-860)
W/art     (20829): Attempt to remove local handle scope entry from IRT, ignoring
I/DEBUG   (  184): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  184): Build fingerprint: 'google/occam/mako:5.0/LRX21T/1576899:user/release-keys'
I/DEBUG   (  184): Revision: '11'
I/DEBUG   (  184): ABI: 'arm'
I/DEBUG   (  184): pid: 20829, tid: 21178, name: Thread-860  >>> com.[censored] <<<
I/DEBUG   (  184): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8d68fc68
I/DEBUG   (  184):     r0 8d68fc68  r1 00000020  r2 000000df  r3 20202020
I/DEBUG   (  184):     r4 00000001  r5 8d68fc68  r6 8d68fc68  r7 a62a0241
I/DEBUG   (  184):     r8 b86f9e13  r9 b86f982a  sl ffffffff  fp 000000ff
I/DEBUG   (  184):     ip 20002000  sp a32988f8  lr a62525f9  pc a62a02bc  cpsr 200b0030
I/DEBUG   (  184): 
I/DEBUG   (  184): backtrace:
I/DEBUG   (  184):     #00 pc 003552bc  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #01 pc 003075f7  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #02 pc 002c450f  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #03 pc 002c4589  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #04 pc 002c6b41  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #05 pc 002c6ffb  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #06 pc 002c4b83  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #07 pc 002c4c51  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #08 pc 002adff5  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #09 pc 002fea4f  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #10 pc 002aa35f  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #11 pc 0032d4ef  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #12 pc 002bd2d1  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #13 pc 00e0ef7b  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #14 pc 00e14a4d  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #15 pc 00e14af3  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #16 pc 00e4cbd1  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #17 pc 00e1ccd1  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #18 pc 00e1ce17  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #19 pc 00204333  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #20 pc 0020458d  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #21 pc 002023cb  /system/lib/libwebviewchromium.so
I/DEBUG   (  184):     #22 pc 000158a7  /system/lib/libc.so (__pthread_start(void*)+30)
I/DEBUG   (  184):     #23 pc 0001387b  /system/lib/libc.so (__start_thread+6)

绘图大约每秒调用一次。直到第 40 次到第 120 次在我的应用程序的单次运行中调用 draw() 时才会发生崩溃。我所有未安装 Lollipop 的测试设备都可以正常工作,不会崩溃。

如果我从 RelativeLayout 中删除 WebView,但保留所有其他元素,也不会发生崩溃。 WebView 会加载网站并正常运行一段时间,直到发生崩溃。如果我不调用 loadUrl(),则不会发生崩溃。无论我加载哪个网站,都会发生崩溃。

我能做些什么来解决这个问题吗?

我在这里找到了一些解决问题的资源:https://groups.google.com/forum/#!topic/android-developers/W6smaM1atE8

但是,在这种情况下使用的功能已被弃用很长时间。

编辑:

这里有一些额外的信息来回答@marcin.kosiba 的问题:

  1. 您传递的 Canvas 是位图支持的 Canvas ,对吗?它有多大?它是否应用了任何转换?

是的,这是前面几行:

Bitmap bmp = Bitmap.createBitmap(someRelativeLayoutContainingWebView.getWidth(), someRelativeLayoutContainingWebView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
someRelativeLayoutContainingWebView.draw(canvas);

如您所见,它是 RelativeLayout 的整个宽度和高度,它占据了设备的整个屏幕,减去设备的状态栏和软后退/主页按钮栏。我的应用程序未在全屏模式下运行。

  1. WebView 显示在屏幕上并呈现到此 Canvas 中,还是 WebView 未附加到 View 层次结构并在后台运行?

WebView 附加到 View 层次结构并出现在屏幕上。它占据了大部分屏幕,只剩下顶部的一个小栏。

  1. 如果您直接调用 WebView.onDraw 也会发生这种情况吗?

除非覆盖 WebView 类,否则我无法直接调用 onDraw()。然而,这样做后,崩溃并没有发生。

  1. 如果您可以创建一个带有重现的 APK 并将其附加到错误,那么查看此内容的人会容易得多。你愿意这样做吗?如果没有,您能否提供有关 RelativeLayout 中其他元素的一些详细信息?

不幸的是,这是一个相当大的项目,Activity 中有很多事情都存在这个问题。我将无法公开共享整个源代码,我知道这会使解决问题变得更加困难。这是 View 层次结构的骨架:

<RelativeLayout android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/someRelativeLayoutContainingWebView">
    <DrawerLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/topRelativeLayout">

        <!-- Main content -->
        <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <WebView
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:id="@+id/primaryWebView"
                        android:scrollbarStyle="insideOverlay"
                        android:fadeScrollbars="true"
                        android:scrollbarThumbVertical="@drawable/scrollbar"
                        android:scrollbarSize="@dimen/scroll_bar_size"/>

                <RelativeLayout>
                    <EditText/>
                    <Button/>
                    <View/>
                    <Button/>
                </RelativeLayout>
            </RelativeLayout>

            <View/>
        </RelativeLayout>

        <!-- Navigation drawer -->
        <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="left">

            <RelativeLayout>
                <TextView/>
                <ViewPager/>
                <View/>

                <LinearLayout>
                    <Button/>
                    <View/>
                    <Button/>
                </LinearLayout>

                <LinearLayout>
                    <Button/>
                </LinearLayout>

                <Button/>
                <Button/>
                <Button/>
            </RelativeLayout>

            <View/>
        </RelativeLayout>

    </DrawerLayout>

    <!-- Top bar -->
    <RelativeLayout android:layout_width="match_parent"
                    android:layout_height="@dimen/some_height"
                    id="@+id/topRelativeLayout">

        <RelativeLayout>
            <SurfaceView/>
            <TextView/>
        </RelativeLayout>

        <Button/>

        <RelativeLayout>
                <EditText/>
                <Button/>
        </RelativeLayout>

    </RelativeLayout>

    <View/>
    <ProgressBar/>
    <TextView/>
</RelativeLayout>

最佳答案

目前不确定您是否可以做任何事情。我提交了 http://crbug.com/441707代表你。了解问题的原因可以更容易地提出解决方法。如果您能澄清一些事情(最好是关于错误),那将会很有帮助:

  1. 您传递的 Canvas 是位图支持的 Canvas,对吗?它有多大?它是否应用了任何转换?
  2. WebView 显示在屏幕上并且被渲染到 Canvas 中,还是 WebView 没有附加到 View 层次结构并在后台运行?
  3. 如果您直接调用 WebView.onDraw 也会发生这种情况吗?
  4. 如果您可以创建一个带有重现的 APK 并将其附加到错误,那么查看此内容的人会容易得多。你愿意这样做吗?如果没有,您能否提供有关 RelativeLayout 中其他元素的一些详细信息?

关于android - WebView.draw(canvas) 有时会在某些设备上的 Android Lollipop 5.0+ 中崩溃 - 致命信号 11 (SIGSEGV),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27431336/

相关文章:

java - Android 旋转器错误 : getOnItemSelectedListener in AdapterView cannot be applied

android - 收到登录尝试的结果时,FirebaseAuthUI 使应用程序崩溃

android - NumberPicker 在禁用时不会变灰

android - 不更新目标 NDK 平台有什么好处吗?

android - 我在哪里可以找到将 Android.mk 转换为 Android.bp 的 androidmk 工具?

android-studio - NDK支持已不支持Android Studio 1.1.0

android - 动态添加多个 View 到 ListView 行

javascript - 如何在需要时将 JavaScript 注入(inject) WebView?

javascript - android webview 只显示部分网页内容

android - 从嵌入式 Android WebView 记录 HTTP 请求的开始和完成