Canvas.native_drawBitmap 中的 ANR

发布于 2024-10-18 05:52:02 字数 2134 浏览 3 评论 0原文

我最近也收到了同样的 ANR 报告。 当应用程序尝试绘制一些位图时(使用 ImageView 作为元素渲染 GridView 时),会发生 ANR。 我已经做了很多调试,现在可以肯定地说挂起既不依赖于位图,也不依赖于它的绘制位置。

堆免费 50%,图像不大于 400px^2
网格元素没有任何自定义布局 - 只是简单的 ImageView。
在 HTC Desire(1 GHz CPU)、Hero、模拟器等上进行测试
ANR 会永远持续,因此就像在绘制位图时正在运行某个无限循环。

还有什么会导致这样的挂起?

报告如下:

DALVIK THREADS:
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x40020ba0 self=0xddd0
  | sysTid=32366 nice=0 sched=0/0 cgrp=unknown handle=-1345025972
  at android.graphics.Canvas.native_drawBitmap(Native Method)
  at android.graphics.Canvas.drawBitmap(Canvas.java:1045)
  at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
  at android.widget.ImageView.onDraw(ImageView.java:860)
  at android.view.View.draw(View.java:6740)
  at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
  at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
  at android.view.View.draw(View.java:6743)
  at android.widget.FrameLayout.draw(FrameLayout.java:352)
  at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
  at android.view.View.draw(View.java:6743)
  at android.widget.FrameLayout.draw(FrameLayout.java:352)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1847)
  at android.view.ViewRoot.draw(ViewRoot.java:1407)
  at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
  at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:4627)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
  at dalvik.system.NativeStart.main(Native Method)

I've been receiving the same ANR reports recently.
The ANR happens when app tries to draw some bitmaps (when rendering a GridView with ImageViews as elements).
I've did a lot of debugging and can now surely say that hangs don't depend neither on bitmap, nor on position where it's being drawn.

The heap is 50% free, images are no bigger than 400px^2
Grid elements doesn't have any custom layout - just simple ImageView.
Tested on HTC Desire (1 GHz CPU), Hero, emulators, etc.
The ANR continues forever so it's like some infinite loop is running while drawing bitmap.

What else can cause such a hang?

The report follows:

DALVIK THREADS:
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x40020ba0 self=0xddd0
  | sysTid=32366 nice=0 sched=0/0 cgrp=unknown handle=-1345025972
  at android.graphics.Canvas.native_drawBitmap(Native Method)
  at android.graphics.Canvas.drawBitmap(Canvas.java:1045)
  at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:323)
  at android.widget.ImageView.onDraw(ImageView.java:860)
  at android.view.View.draw(View.java:6740)
  at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
  at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
  at android.view.View.draw(View.java:6743)
  at android.widget.FrameLayout.draw(FrameLayout.java:352)
  at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
  at android.view.View.draw(View.java:6743)
  at android.widget.FrameLayout.draw(FrameLayout.java:352)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1847)
  at android.view.ViewRoot.draw(ViewRoot.java:1407)
  at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
  at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:4627)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
  at dalvik.system.NativeStart.main(Native Method)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉墨 2024-10-25 05:52:02

如果没有代码或至少没有一个小样本,就很难查明您的问题。您可能需要使用 AsyncTask 加载图像。另外打开 StrictMode 对于查找 ANR 错误非常有帮助。

public void onCreate() {
 if (DEVELOPER_MODE) {
     StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
             .detectDiskReads()
             .detectDiskWrites()
             .detectNetwork()   // or .detectAll() for all detectable problems
             .penaltyLog()
             .build());
     StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
             .detectLeakedSqlLiteObjects()
             .detectLeakedClosableObjects()
             .penaltyLog()
             .penaltyDeath()
             .build());
 }
 super.onCreate();
 }

确保在发布之前删除 StrictMode。它将在 api 级别 9 之前的设备上导致验证错误。
这是在开发过程中使用的一个很好的功能。当您执行可能阻塞 UI 线程的操作时,它会导致您的应用程序正常崩溃。

It's very hard to pinpoint your problem without your code or at least a small sample. You probably need to load you images using AsyncTask. Also turning on StrictMode is very helpful for finding ANR errors.

public void onCreate() {
 if (DEVELOPER_MODE) {
     StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
             .detectDiskReads()
             .detectDiskWrites()
             .detectNetwork()   // or .detectAll() for all detectable problems
             .penaltyLog()
             .build());
     StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
             .detectLeakedSqlLiteObjects()
             .detectLeakedClosableObjects()
             .penaltyLog()
             .penaltyDeath()
             .build());
 }
 super.onCreate();
 }

Make sure to remove StrictMode before you release. It will cause a VerifyError on devices before api level 9.
It's a nice feature to use during development. It will cause your app to crash gracefully when ever you do something that might block the UI thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文