我正在使用 Opencv sdk for Android 来开发实时处理和匹配。
主要的Opencv特征逻辑是在JNI
函数中。
问题是有时(只是有时)我的应用程序崩溃而没有错误,所以我忽略了这个问题,直到我完成算法的开发。
我开始调查错误,它肯定在 JNI 部分。
这是我在Log
中遇到的错误
A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 27424 (Thread-8)
A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
我在互联网上搜索了很多,我找到了这个解决方案
<activity
android:hardwareAccelerated="false" />
它工作了 2 天,现在我又收到同样的错误。
问题是什么,我该如何解决?
任何帮助将不胜感激,并提前感谢您。
编辑
我应该补充一点,我的应用程序从库中获取参考图像,并使用 Opencv 将其与实时图像馈送进行比较。
如果我从图库中选择一个图像并且应用程序崩溃,则该图像将无法再次工作,如果我拍摄新图像或以前工作的图像,该应用程序将正常工作。
我解决了
-
重新启动我的智能手机(物理设备)。
-
如果您使用的是Android Studio,请转到文件-->无效缓存并重新启动。
如果您使用的是 android 模拟器,请尝试 [冷启动] 它
经过一番讨论,很明显问题出在与记忆的交互上:
extern "C"
jdouble
JNICALL Java_com_foo(JNIEnv *env, jclass type, jlong addrRgba, jlong addrGray) {
Mat &mRgb = *(Mat *) addrRgba;
Mat &mGray = *(Mat *) addrGray;
return (jdouble) toGray(mRgb, mGray);
}
作为快速修复,double toGray(Mat& rgb, Mat& gray);
必须更改为double toGray(Mat rgb, Mat gray)
有关主题CvMat deep copy
的更多信息
就我而言,我将问题范围缩小到在片段中加载Admob广告。 但仅当屏幕第二次呈现时。
示例:我离开屏幕,然后通过 FragmentManager 返回屏幕。
无论如何,如果是 adview,您可以通过关闭 AndroidManifest 中的硬件加速来修复.xml,甚至更好的是,直接在广告组件本身上关闭硬件加速:
val adRequest: AdRequest = AdRequest.Builder().build()
// disable hardware acceleration on this view, as it was causing the screen to crash on reload.
adView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
adView.loadAd(adRequest)
将其缩小到这个有点棘手,但我注意到了这一点:
I/DynamiteModule:考虑本地模块com.google.android.gms.ads.dynamite:0和远程模块com.google.android.gms.ads.dynamite:204204100
消息正上方
" 致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 19705 (渲染线程) 中的故障地址0x0,pid 19631">
为我解决此问题的最简单方法是卸载并重新安装该应用程序。
这个问题确实发生在我身上,但经过验证的答案没有帮助。相反,此线程中其他答案的组合确实如此。 简而言之,我所做的只是:
-
使 Android Studio 的缓存失效。
-
擦除设备的数据并冷启动。
就我而言,当我开始在模拟器上使用它时,我正在使用带有iPad的Macbook Pro作为外部屏幕(sidecar模式)。
断开边车后。它工作正常。
就我而言,当我尝试收听imageReader.acquireLatestImage() {image -> //do smth}
时,当该阅读器已被imageReader.close()
关闭时,捕获了一个异常。 这是因为我有几个 imageReader,其中至少有一个在关闭之前没有时间给出新图像,并且在关闭和回调调用之间有一个很小的时间间隔。
尝试使文件中的 Android Studio 缓存失效-> 使缓存失效/重新启动
另外,检查是否没有其他严重错误(您可以在应用程序崩溃后在 Logcat 中看到它们)。
解决方案:确保 openCV 上有一个实例处理数据。 添加一个标志以检查是否有其他进程正在处理图像。
原因:这是由于具有多个不受控制的 openCV 实例而导致的。如果您正在使用 tflite,则同样适用
我尝试在build.gradle中禁用爱马仕,它起作用了。