HeifDecoderImpl 导致 'decStrong() called too many times'

HeifDecoderImpl causes 'decStrong() called too many times'

我的 Android 应用“照片比较”(https://github.com/sniederb/photocompare) 使用“子采样比例图像视图”(来自 Dave Morrissey)来显示图像,并允许缩放和平移。这几乎总是有效,但在 Android 11 上使用 HEIC 图像时,activity 在我放大时立即崩溃。

正在中止的线程是

    runtime.cc:655] Aborting thread:
    runtime.cc:655] "HeifDecode" prio=6 tid=32 Native
    runtime.cc:655]   | group="" sCount=0 dsCount=0 flags=0 obj=0x12c40020 self=0xe9022210
    runtime.cc:655]   | sysTid=18958 nice=-2 cgrp=top-app sched=0/0 handle=0xc6e561e0
    runtime.cc:655]   | state=R schedstat=( 98486663 91130505 137 ) utm=2 stm=7 core=2 HZ=100
    runtime.cc:655]   | stack=0xc6d5b000-0xc6d5d000 stackSize=1008KB
    runtime.cc:655]   | held mutexes= "abort lock"
    runtime.cc:655]   native: #00 pc 00542d9e  /apex/com.android.art/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+110)
    runtime.cc:655]   native: #01 pc 006a0897  /apex/com.android.art/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+1015)
    runtime.cc:655]   native: #02 pc 0069a171  /apex/com.android.art/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+65)
    runtime.cc:655]   native: #03 pc 006522c5  /apex/com.android.art/lib/libart.so (art::AbortState::DumpThread(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, art::Thread*) const+53)
    runtime.cc:655]   native: #04 pc 00639abb  /apex/com.android.art/lib/libart.so (art::Runtime::Abort(char const*)+2587)
    runtime.cc:655]   native: #05 pc 00025a23  /apex/com.android.art/lib/libartbase.so (std::__1::__function::__func<void (*)(char const*), std::__1::allocator<void (*)(char const*)>, void (char const*)>::operator()(char const*&&)+35)
    runtime.cc:655]   native: #06 pc 0001588f  /system/lib/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+79)
    runtime.cc:655]   native: #07 pc 00006dbd  /system/lib/liblog.so (__android_log_assert+285)
    runtime.cc:655]   native: #08 pc 000102a2  /system/lib/libutils.so (android::RefBase::decStrong(void const*) const+146)
    runtime.cc:655]   native: #09 pc 00004de4  /system/lib/libheif.so (android::HeifDecoderImpl::decodeAsync()+436)
    runtime.cc:655]   native: #10 pc 00004c23  /system/lib/libheif.so (android::HeifDecoderImpl::DecodeThread::threadLoop()+35)
    runtime.cc:655]   native: #11 pc 00015116  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+374)
    runtime.cc:655]   native: #12 pc 00098fee  /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+174)
    runtime.cc:655]   native: #13 pc 000147d9  /system/lib/libutils.so (thread_data_t::trampoline(thread_data_t const*)+457)
    runtime.cc:655]   native: #14 pc 000e6974  /apex/com.android.runtime/lib/bionic/libc.so (__pthread_start(void*)+100)
    runtime.cc:655]   native: #15 pc 00078567  /apex/com.android.runtime/lib/bionic/libc.so (__start_thread+71)
    runtime.cc:655]   (no managed stack frames)

并且崩溃报告指出

2021-01-09 14:12:53.736 19089-19089/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2021-01-09 14:12:53.736 19089-19089/? A/DEBUG: Build fingerprint: 'google/sdk_gphone_x86_arm/generic_x86_arm:11/RSR1.201013.001/6903271:userdebug/dev-keys'
2021-01-09 14:12:53.736 19089-19089/? A/DEBUG: Revision: '0'
2021-01-09 14:12:53.737 19089-19089/? A/DEBUG: ABI: 'x86'
2021-01-09 14:12:53.737 19089-19089/? A/DEBUG: Timestamp: 2021-01-09 14:12:53+0100
2021-01-09 14:12:53.737 19089-19089/? A/DEBUG: pid: 18085, tid: 18958, name: HeifDecode  >>> ch.want.imagecompare <<<
2021-01-09 14:12:53.737 19089-19089/? A/DEBUG: uid: 10153
2021-01-09 14:12:53.737 19089-19089/? A/DEBUG: signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
2021-01-09 14:12:53.738 19089-19089/? A/DEBUG: Abort message: 'decStrong() called on 0xc7e43d10 too many times'
2021-01-09 14:12:53.738 19089-19089/? A/DEBUG:     eax 00000000  ebx 000046a5  ecx 00004a0e  edx 00000006
2021-01-09 14:12:53.738 19089-19089/? A/DEBUG:     edi f4a5681e  esi c6e559c0
2021-01-09 14:12:53.738 19089-19089/? A/DEBUG:     ebp f7517b90  esp c6e55968  eip f7517b99
2021-01-09 14:12:53.744 19089-19089/? A/DEBUG: backtrace:
2021-01-09 14:12:53.745 19089-19089/? A/DEBUG:       #00 pc 00000b99  [vdso] (__kernel_vsyscall+9)
2021-01-09 14:12:53.745 19089-19089/? A/DEBUG:       #01 pc 0005ad68  /apex/com.android.runtime/lib/bionic/libc.so (syscall+40) (BuildId: 6e3a0180fa6637b68c0d181c343e6806)
2021-01-09 14:12:53.745 19089-19089/? A/DEBUG:       #02 pc 00076511  /apex/com.android.runtime/lib/bionic/libc.so (abort+209) (BuildId: 6e3a0180fa6637b68c0d181c343e6806)
2021-01-09 14:12:53.745 19089-19089/? A/DEBUG:       #03 pc 00639a4d  /apex/com.android.art/lib/libart.so (art::Runtime::Abort(char const*)+2477) (BuildId: 8191579dfafff37a5cbca70f9a73020f)
2021-01-09 14:12:53.745 19089-19089/? A/DEBUG:       #04 pc 00025a23  /apex/com.android.art/lib/libartbase.so (std::__1::__function::__func<void (*)(char const*), std::__1::allocator<void (*)(char const*)>, void (char const*)>::operator()(char const*&&)+35) (BuildId: 41e9e0cbb5db4bb6875333d66af6569f)
2021-01-09 14:12:53.746 19089-19089/? A/DEBUG:       #05 pc 0001588f  /system/lib/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+79) (BuildId: 3abc3ce4c3b633a64b14c50cb931a64b)
2021-01-09 14:12:53.746 19089-19089/? A/DEBUG:       #06 pc 00006dbd  /system/lib/liblog.so (__android_log_assert+285) (BuildId: bbac430fc6349b937996bb914e70c060)
2021-01-09 14:12:53.746 19089-19089/? A/DEBUG:       #07 pc 000102a2  /system/lib/libutils.so (android::RefBase::decStrong(void const*) const+146) (BuildId: ab4be013cda31e8c45d48aa23a89d0f8)
2021-01-09 14:12:53.746 19089-19089/? A/DEBUG:       #08 pc 00004de4  /system/lib/libheif.so (android::HeifDecoderImpl::decodeAsync()+436) (BuildId: 49a068f457bf8577f622fb97089c3c5d)
2021-01-09 14:12:53.746 19089-19089/? A/DEBUG:       #09 pc 00004c23  /system/lib/libheif.so (android::HeifDecoderImpl::DecodeThread::threadLoop()+35) (BuildId: 49a068f457bf8577f622fb97089c3c5d)
2021-01-09 14:12:53.746 19089-19089/? A/DEBUG:       #10 pc 00015116  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+374) (BuildId: ab4be013cda31e8c45d48aa23a89d0f8)
2021-01-09 14:12:53.747 19089-19089/? A/DEBUG:       #11 pc 00098fee  /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+174) (BuildId: 588f2cd5873ff4273bb25b25edb82606)
2021-01-09 14:12:53.747 19089-19089/? A/DEBUG:       #12 pc 000147d9  /system/lib/libutils.so (thread_data_t::trampoline(thread_data_t const*)+457) (BuildId: ab4be013cda31e8c45d48aa23a89d0f8)
2021-01-09 14:12:53.747 19089-19089/? A/DEBUG:       #13 pc 000e6974  /apex/com.android.runtime/lib/bionic/libc.so (__pthread_start(void*)+100) (BuildId: 6e3a0180fa6637b68c0d181c343e6806)

到目前为止,我的理解是 HeifDecoderImpl 被要求异步解码图像区域(这是“子采样比例图像视图”所做的,afaik),并且在这样做时试图过于频繁地释放资源,导致 RefBase过于频繁地尝试减少强引用计数。

作为一名应用程序程序员,我很困惑,不确定我是否能在这里做些什么。 HeifDecoderImpl 和 RefBase 似乎都是核心 Android 代码。我是否需要查看“子采样比例图像视图”库?任何指针表示赞赏。

看来错误是由于 SubsamplingScaleImageView 使用的 Bitmap.Config.RGB_565 的默认 Bitmap.Config(实际上在 SkiaImageDecoder.java,该包的一部分)。通过切换到

SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.ARGB_8888);

错误消失。