我有一段代码在UI线程上运行,要求RelativeLayout
使用WebView
绘制到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的所有测试设备工作正常,不会崩溃。
如果我从WebView
删除RelativeLayout
,但保留所有其他元素,也不会发生崩溃。 WebView
确实会加载网站并正常运行一段时间,直到崩溃发生。如果我不调用loadUrl()
,则不会发生崩溃。无论我加载哪个网站,都会发生崩溃。
我能做些什么来解决这个问题吗?
我在这里找到了解决问题的一些资源:https://groups.google.com/forum/#!topic/android-developers/W6smaM1atE8
但是,在这种情况下使用的函数已经被弃用了很长时间。
以下是回应@ marcin.kosiba的问题的其他信息:
是的,这是前面几行:
Bitmap bmp = Bitmap.createBitmap(someRelativeLayoutContainingWebView.getWidth(), someRelativeLayoutContainingWebView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
someRelativeLayoutContainingWebView.draw(canvas);
正如您所看到的,它是RelativeLayout
的整个宽度和高度,占据设备的整个屏幕,减去设备的状态栏和软后退/主页按钮栏。我的应用程序无法以全屏模式运行。
WebView附加到视图层次结构并显示在屏幕上。它占据了屏幕的大部分,减去了顶部的一个小条。
除非我覆盖onDraw()
类,否则我无法直接调用WebView
。但是,在这样做时,没有发生崩溃。
不幸的是,这是一个非常大的项目,Activity
中有很多事情发生了这个问题。我无法公开分享整个源代码,我知道,这使得解决问题变得更加困难。以下是视图层次结构的框架:
<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>
答案 0 :(得分:1)
此时不确定是否有任何可以做的事情。我代表您提交了http://crbug.com/441707。了解问题的原因可以更容易地提出解决方法。如果你能澄清一些事情(最好是关于bug)会很有帮助:
答案 1 :(得分:0)
问题来自竞争条件,有时会导致我的代码吸引属于回收Canvas
的{{1}}。可以使用以下代码重现崩溃:
Bitmap
修复竞争条件并确保永远不会使用回收的Bitmap bmp = Bitmap.createBitmap(someRelativeLayoutContainingWebView.getWidth(), someRelativeLayoutContainingWebView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
bmp.recycle();
someRelativeLayoutContainingWebView.draw(canvas); // SIGSEGV will happen here
Bitmap
来解决问题。
另一个有趣的细节是,如果从视图层次结构中删除了Canvas
,则会抛出WebView
而不是RuntimeException
。异常的重要部分如下所示:
SIGSEGV
这比E/AndroidRuntime( 7052): Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1cb64604
E/AndroidRuntime( 7052): at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1225)
E/AndroidRuntime( 7052): at android.graphics.Canvas.<init>(Canvas.java:152)
崩溃更有用。