我的Android应用程序突然关闭

我的Android应用程序突然关闭,android,opencv,android-asynctask,java-native-interface,android-camera,Android,Opencv,Android Asynctask,Java Native Interface,Android Camera,我正在用OpenCV开发一个增强现实Android应用程序 现在,当我运行我的应用程序时,它会运行几秒钟,然后突然关闭,没有警告,logcat中也没有错误消息。我认为这与RAM内存耗尽有关,但我很难弄清楚这是什么原因造成的。此外,当我在我的应用程序突然关闭时检查ddms时,所有进程(不仅仅是我的应用程序)都开始消失。有时我会在logcat中收到这样的错误消息: cannot map BpMemoryHeap (binder=0x767e84c0), size=2883584, fd=53 (Ou

我正在用OpenCV开发一个增强现实Android应用程序

现在,当我运行我的应用程序时,它会运行几秒钟,然后突然关闭,没有警告,logcat中也没有错误消息。我认为这与RAM内存耗尽有关,但我很难弄清楚这是什么原因造成的。此外,当我在我的应用程序突然关闭时检查ddms时,所有进程(不仅仅是我的应用程序)都开始消失。有时我会在logcat中收到这样的错误消息:

cannot map BpMemoryHeap (binder=0x767e84c0), size=2883584, fd=53 (Out of memory)
以下是我的OnPreviewFrame的设置方式:

  • 添加一些回调缓冲区:

    float bytesPerPix = ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8.0f;
    int frame_byteSize = (int) ((size.width * size.height) * bytesPerPix);
    
    for(int i = 0; i< AppConfig.AMOUNT_PREVIEW_BUFFERS ; i++) {
        camera.addCallbackBuffer(new byte[frame_byteSize]);
    }
    
  • 以下是在OnPreviewFrame方法中调用的updateCameraPose函数:

    public void updateCameraPose(byte[] frameData, Camera camera) {
    
        Size size = camera.getParameters().getPreviewSize();
    
        Mat frameImg = new Mat();
        Mat mYuv = new Mat( size.height + size.height/2, size.width, CvType.CV_8UC1 );
        mYuv.put( 0, 0, frameData );
    
        camera.addCallbackBuffer(frameData);
    
        Imgproc.cvtColor( mYuv, frameImg, Imgproc.COLOR_YUV2GRAY_NV21, 1);
    
        FindCameraPose task = new FindCameraPose();
        task.execute(frameImg, cameraPose);
    
    }
    
    此函数调用并执行asynctask,下面是我的asynctask的代码:

    private class FindCameraPose extends AsyncTask<Mat, Void, Mat> {
    
        @Override
        protected Mat doInBackground(Mat... params) {
            String t = cameraIntDistPath;
            getCameraPose( 
                    params[0].getNativeObjAddr(), 
                    t, 
                    params[1].getNativeObjAddr());
            return params[1];
        }
    
        @Override
        protected void onPostExecute(Mat result) {
            super.onPostExecute(result);
            if(result != null && !result.empty())
                Log.d(TAG, "Camera Pose: "+result.dump());
        }
        private native boolean getCameraPose(long frameImagePtr, String cameraIntDistPath, long cameraPosePtr);
    
    }
    
    有什么想法吗

    更新

    好的,我把内存泄漏缩小到了本机堆中的一个泄漏,它来自opencv_java库。特别是当我关掉检测关键点的电话时,泄漏似乎消失了。我希望这不是OpenCV中的错误,但现在看起来是这样的。此外,即使我尝试使用另一个检测器(SIFT/SURF/ORB/BRISK),这也没关系,仍然是内存泄漏

    有人知道这可能与什么有关吗?

    您是否尝试将“android:largeHeap=“true”参数放在AndroidManifest.xml中的应用程序标记中

    大概是这样的:

    <application android:label="@string/app_name" android:largeHeap="true">
    
    <activity android:name=".MainActivity" android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
    
    

    好的,我刚才回答了我自己的问题

    在计算完成之前,我将回调缓冲区返回给了相机,并且在每一帧上都是如此。这使相机可以在几乎每一帧上运行getCameraPose方法(这当然是很多)。这几乎每一帧都会调用跟踪代码,因此添加的工作比可以解决的要多,这就解释了堆中使用的大量内存


    从现在起,我将确保只有在完全处理完帧后才将缓冲区还给相机。

    遗憾的是,这没有帮助。然后,可能您必须减小图像缓冲区的大小。更改分辨率或将颜色类型更改为les deph。很抱歉,我无法在这方面为您提供更多帮助。我无法想象这会发生LP,因为我刚刚看到我的堆大小,当我的应用程序崩溃时,它大约是1GB。所以这肯定是我的C++代码中的内存泄漏。考虑使用OpenCV本地相机,在你的场景中它可能比java相机更有效。是的,我知道这可能会更好。问题是我也使用纸板VR SDK FR。om Google和我认为如果我使用OpenCV本机摄像头,那么使用它将成为一个问题(因为两个API都需要自己的视图)。
    JNIEXPORT jboolean JNICALL Java_be_wouterfranken_arboardgame_rendering_tracking_CameraPose_00024FindCameraPose_getCameraPose
          (JNIEnv * env, jobject jobject, jlong frameImagePtr, jstring cameraIntDistPath, jlong cameraPosePtr)
    {
        Mat *camPose = (Mat *) cameraPosePtr;
        Mat *frameImage = (Mat *) frameImagePtr;
    
        __android_log_print(ANDROID_LOG_DEBUG,APPNAME, "Mats setup ...");
    
        const char * path = env->GetStringUTFChars(cameraIntDistPath, NULL);
    
        __android_log_print(ANDROID_LOG_DEBUG,APPNAME, "Path string setup started ... %s",path);
    
        Mat intrinsics;
        Mat distortion;
    
        __android_log_print(ANDROID_LOG_DEBUG,APPNAME, "Search for cameraPose started...");
    
        Utilities::loadCameraCalibration(path, intrinsics, distortion);
        env->ReleaseStringUTFChars(cameraIntDistPath, path);
    
        __android_log_print(ANDROID_LOG_DEBUG,APPNAME, "Camera calibration done");
    
        bool patternFound = pd.findPattern(*frameImage, pti);
    
        __android_log_print(ANDROID_LOG_DEBUG,APPNAME, "Patterns found? %d",patternFound);
    
        if(patternFound) {
            pti.computePose(p, intrinsics, distortion);
            *camPose = pti.pose3d;
            __android_log_print(ANDROID_LOG_DEBUG,APPNAME, "Pose computed");
        }
    
        return patternFound;
    }
    
    <application android:label="@string/app_name" android:largeHeap="true">
    
    <activity android:name=".MainActivity" android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>