【问题标题】:Android MediaRecorder stop() not being calledAndroid MediaRecorder stop() 未被调用
【发布时间】:2016-12-06 01:53:37
【问题描述】:

我有一个非常奇怪的错误,我的一些代码没有被调用,但看起来没有任何理由不调用它。

onFinishedRecording 被调用并且标签"Finished recording." 被注销,但之后的代码根本不会被调用。当调用mMediaRecorder.stop(); 时,所有代码都将停止调用。它也不会进入 catch 块。为什么会这样?

我认为这可能与不同的线程有关,但我检查了所有线程名称,它们都在同一个主线程上运行。

另外,我的相机预览设置有问题吗?当我尝试播放视频时,它已损坏且无法播放。

除了上述问题,我的后退按钮在应用程序中没有任何作用。没有完全说明为什么或如何与我实现的代码相关。

MyLibrary 类(库模块类)

public class MyLibrary implements PreciseCountdownTimer.PreciseCountdownTimerCallback {

    private static final String TAG = AngryOtter.class.getSimpleName();
    private static final long MAX_RECORD_TIME_MILLIS = 3000;
    private static final long INTERVAL_MILLIS = 1000;

    private static MyLibrary mInstance;

    private Activity mActivity;
    private CameraInitListener mCallback;

    private int mCameraId = -1;
    private Camera mCamera;
    private SurfaceView mCameraPreview;
    private MediaRecorder mMediaRecorder;
    private PreciseCountdownTimer mTimer;
    private File mTempVideoFile;

    public static MyLibrary getInstance() {
        if (mInstance == null) {
            mInstance = new MyLibrary();
        }
        return mInstance;
    }

    // Call this in onResume of the activity
    public void initialize(Activity activity) {
        mActivity = activity;

        try {
            mCallback = (CameraInitListener) mActivity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.getClass().getSimpleName()
                    + " must implement CameraInitListener");
        }

        if (ViewUtil.checkValidRootView(mActivity)) {
            PermissionUtil.requestPermissions(mActivity);
            prepareCamera();
            if (mCamera == null) {
                return;
            }
            addCameraPreview();
        }
    }

    // Call this in onPause of the activity
    public void release() {
        releaseMediaRecorder();
        releaseCamera();
        removeCameraPreview();
        releaseTimer();
    }

    public void startRecording() {
        if (checkPermissions()) {
            try {
                mMediaRecorder.start();
                mTimer.start();
                Log.d(TAG, "Recording started.");
            } catch (IllegalStateException e) {
                releaseMediaRecorder();
                releaseTimer();
            }
        } else {
            releaseMediaRecorder();
        }
    }

    public void stopRecording() {
        onFinishedRecording();
    }

    @Override
    public void onPreciseTimerTick(long remainingTime) {
        Log.d(TAG, "TICK: " + String.valueOf(remainingTime));
    }

    @Override
    public void onPreciseTimerFinished() {
        Log.d(TAG, "Timer Finished.");
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                onFinishedRecording();
            }
        });
    }

    private boolean checkPermissions() {
        if (PermissionUtil.checkCameraPermission(mActivity)
                && PermissionUtil.checkRecordAudioPermission(mActivity)
                && PermissionUtil.checkWriteExternalStoragePermission(mActivity)) {
            return true;
        } else {
            return false;
        }
    }

    private void prepareCamera() {
        mCameraId = CameraUtil.getFrontCameraId();
        if (mCameraId != -1) {
            try {
                Log.d(TAG, "Initializing front camera.");
                mCamera = Camera.open(mCameraId);
            } catch (Exception e) {
                Log.e(TAG, "Error initializing front camera: " + e.getMessage());
                mCamera = null;
            }
        } else {
            mCamera = null;
        }
    }

    private void releaseCamera() {
        if (mCamera != null){
            Log.d(TAG, "Releasing camera.");
            mCamera.release();
            mCamera = null;
        }
    }

    private void addCameraPreview() {
        mCameraPreview = new SurfaceView(mActivity);
        mCameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "Preview surface created.");
                try {
                    Log.d(TAG, "Setting preview display.");
                    mCamera.setPreviewDisplay(holder);
                    mCamera.startPreview();
                    onPreviewDisplaySet();
                } catch (IOException e) {
                    Log.e(TAG, "Error setting camera preview: " + e.getMessage());
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.d(TAG, "Preview surface changed.");
                // If your preview can change or rotate, take care of those events here.
                // Make sure to stop the preview before resizing or reformatting it.

                if (mCameraPreview.getHolder().getSurface() == null) {
                    // preview surface does not exist
                    return;
                }

                // stop preview before making changes
                try {
                    mCamera.stopPreview();
                } catch (Exception e){
                    // ignore: tried to stop a non-existent preview
                }

                // Adjust orientation
                final int rotation = CameraUtil.getAdjustedDisplayOrientation(mActivity, mCameraId);
                mCamera.setDisplayOrientation(rotation);

                // set preview size and make any resize, rotate or
                // reformatting changes here

                // start preview with new settings
                try {
                    mCamera.setPreviewDisplay(mCameraPreview.getHolder());
                    mCamera.startPreview();
                } catch (Exception e){
                    Log.d(TAG, "Error starting camera preview: " + e.getMessage());
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "Preview surface destroyed.");
            }
        });
        mCameraPreview.setLayoutParams(new FrameLayout.LayoutParams(100, 100, Gravity.TOP|Gravity.RIGHT));
        mCameraPreview.setBackgroundColor(ContextCompat.getColor(mActivity, android.R.color.holo_red_dark));

        final WindowManager windowManager =
                (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(1, 1,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0, PixelFormat.UNKNOWN);
        windowManager.addView(mCameraPreview, layoutParams);
    }

    private void removeCameraPreview() {
        if (mCameraPreview != null) {
            final ViewGroup rootView = ViewUtil.getRootView(mActivity);
            rootView.removeView(mCameraPreview);
        }
    }

    private void onPreviewDisplaySet() {
        createTempVideoFile();

        prepareMediaRecorder();
        if (mMediaRecorder == null) {
            return;
        }

        prepareTimer();
        mCallback.onCameraInitialized();
    }

    private void createTempVideoFile() {
        mTempVideoFile = FileUtil.getTempVideoFile(mActivity);
    }

    private void prepareMediaRecorder() {
        if (mCamera != null) {
            mCamera.unlock();
        }

        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setCamera(mCamera);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setProfile(CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_HIGH));
        mMediaRecorder.setOutputFile(mTempVideoFile.getAbsolutePath());
        mMediaRecorder.setPreviewDisplay(mCameraPreview.getHolder().getSurface());
//        mMediaRecorder.setOrientationHint(90);

        try {
            Log.d(TAG, "Preparing media recorder.");
            mMediaRecorder.prepare();
        } catch (IllegalStateException|IOException e) {
            Log.e(TAG, "Error preparing MediaRecorder: " + e.getMessage());
            releaseMediaRecorder();
        }
    }

    private void releaseMediaRecorder() {
        if (mMediaRecorder != null) {
            Log.d(TAG, "Releasing media recorder.");
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
        }

        if (mCamera != null) {
            mCamera.lock();
        }
    }

    private void prepareTimer() {
        mTimer = new PreciseCountdownTimer(MAX_RECORD_TIME_MILLIS, INTERVAL_MILLIS, this);
    }

    private void releaseTimer() {
        if (mTimer != null) {
            Log.d(TAG, "Stopping timer.");
            mTimer.stop();
        }
    }

    private void onFinishedRecording() {
        Log.d(TAG, "Finished recording.");
        try {
            mMediaRecorder.stop();
            Log.d(TAG, "Media recorder stopped.");
        } catch (Exception e) {
            e.printStackTrace();
        }

        releaseMediaRecorder();
        releaseTimer();
        getSignedUrl();
    }

    private void getSignedUrl() {
        new GcpSigningRequest(new NetworkCallback<String>() {
            @Override
            public void onSuccess(String response) {
                uploadVideo(response);
            }

            @Override
            public void onError() {
                Log.e(TAG, "Error getting signing request.");
            }
        }).addToQueue();
    }

    private void uploadVideo(String signedUrl) {
        new UploadToGoogleRequest(signedUrl, mTempVideoFile.getName(),
                Uri.parse(mTempVideoFile.getAbsolutePath()), new NetworkCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean response) {

            }

            @Override
            public void onError() {

            }
        }).addToQueue();
    }
}

记录活动

public class RecordActivity extends AppCompatActivity implements
        CameraInitListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();
        MyLibrary.getInstance().initialize(this);
    }

    @Override
    protected void onPause() {
        MyLibrary.getInstance().release();
        super.onPause();
    }

    @Override
    public void onCameraInitialized() {
        MyLibrary.getInstance().startRecording();
    }
}

所以在调用此方法之前一切正常:

    private void onFinishedRecording() {
        Log.d(TAG, "Finished recording.");
        try {
            mMediaRecorder.stop();
            Log.d(TAG, "Media recorder stopped.");
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

        releaseMediaRecorder();
        releaseTimer();
        getSignedUrl();
    }

完整的电话堆栈跟踪

08-15 21:17:46.735 24660-24660/com.walintukai.heatmapdemo I/dalvikvm: Could not find method android.content.res.Resources.getDrawable, referenced from method android.support.v7.widget.ResourcesWrapper.getDrawable
08-15 21:17:46.735 24660-24660/com.walintukai.heatmapdemo W/dalvikvm: VFY: unable to resolve virtual method 690: Landroid/content/res/Resources;.getDrawable (ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
08-15 21:17:46.735 24660-24660/com.walintukai.heatmapdemo D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
08-15 21:17:46.735 24660-24660/com.walintukai.heatmapdemo I/dalvikvm: Could not find method android.content.res.Resources.getDrawableForDensity, referenced from method android.support.v7.widget.ResourcesWrapper.getDrawableForDensity
08-15 21:17:46.735 24660-24660/com.walintukai.heatmapdemo W/dalvikvm: VFY: unable to resolve virtual method 692: Landroid/content/res/Resources;.getDrawableForDensity (IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
08-15 21:17:46.735 24660-24660/com.walintukai.heatmapdemo D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
08-15 21:17:46.785 933-11266/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:46.785 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:46.785 731-2931/? E/EnterpriseContainerManager: ContainerPolicy Service is not yet ready!!!
08-15 21:17:46.785 731-2931/? D/EnterpriseDeviceManager: ContainerId: 0
08-15 21:17:46.785 731-2931/? W/LicenseLogService: log() failed
08-15 21:17:46.805 170-170/? E/SMD: DCD ON
08-15 21:17:46.865 933-11213/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:46.865 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:46.935 380-24718/? E/mm-camera: color_correct_apply_gain: cc_gain_adj 1.000, digital_gain_brightness 1.000 dig_gain = 1.000
08-15 21:17:47.055 731-24783/? W/ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1509 com.android.server.InputMethodManagerService$4.run:2683 java.lang.Thread.run:841 <bottom of call stack> <bottom of call stack> 
08-15 21:17:47.145 174-234/? E/qdmemalloc: heap_msk=3000000 flags=1

08-15 21:17:47.165 174-234/? E/qdmemalloc: heap_msk=40000000 flags=1

08-15 21:17:47.185 933-10839/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.185 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.225 933-947/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.245 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.265 933-10842/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.275 174-940/? E/qdmemalloc: heap_msk=3000000 flags=1

08-15 21:17:47.275 174-940/? E/qdmemalloc: heap_msk=40000000 flags=1

08-15 21:17:47.285 24660-24660/com.walintukai.heatmapdemo D/RecordingService: Tick: 2000
08-15 21:17:47.295 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.305 179-24742/? W/CameraSource: Timed out waiting for incoming camera video frames: 0 us
08-15 21:17:47.375 933-11213/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.375 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.506 933-953/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.506 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.666 731-838/? D/PackageManager: [MSG] CHECK_PENDING_VERIFICATION
08-15 21:17:47.766 179-460/? D/AudioStreamOutALSA: standby
08-15 21:17:47.766 179-460/? D/ALSAModule: s_standby: handle 0xb7c24650 h 0x0
08-15 21:17:47.766 179-460/? E/ALSAModule: s_standby handle h 0xb7ceb678
08-15 21:17:47.836 933-6432/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.846 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.846 174-234/? I/SurfaceFlinger: id=833 Removed ieatmapdemo (12/17)
08-15 21:17:47.846 174-940/? I/SurfaceFlinger: id=833 Removed ieatmapdemo (-2/17)
08-15 21:17:47.896 933-11464/? D/KeyguardUpdateMonitor: sendKeyguardVisibilityChanged(true)
08-15 21:17:47.906 933-933/? D/KeyguardUpdateMonitor: handleKeyguardVisibilityChanged(1)
08-15 21:17:47.956 179-460/? D/ALSAModule: checkRunningHandle return false
08-15 21:17:47.956 179-460/? D/alsa_ucm: snd_use_case_set(): uc_mgr 0xb7bf62a0 identifier _verb value Inactive
08-15 21:17:47.956 179-460/? D/alsa_ucm: Set mixer controls for HiFi enable 0
08-15 21:17:47.956 179-460/? D/alsa_ucm: Setting mixer control: PRI_RX Audio Mixer MultiMedia1, value: 0
08-15 21:17:47.956 179-460/? E/ALSAModule: Number of modifiers 1
08-15 21:17:47.956 179-460/? E/ALSAModule: index 0 modifier Capture Music
08-15 21:17:47.956 179-460/? E/ALSAModule: use case is Capture Music
08-15 21:17:47.956 179-460/? E/ALSAModule: usecase_type is 2
08-15 21:17:47.956 179-460/? D/alsa_ucm: snd_use_case_set(): uc_mgr 0xb7bf62a0 identifier _disdev value Speaker
08-15 21:17:47.956 179-460/? D/alsa_ucm: Set mixer controls for Speaker enable 0
08-15 21:17:47.956 179-460/? D/alsa_ucm: Setting mixer control: RX5 MIX1 INP1, value: ZERO
08-15 21:17:47.966 179-460/? D/alsa_ucm: Setting mixer control: RX5 MIX1 INP2, value: ZERO
08-15 21:17:47.966 179-460/? D/alsa_ucm: Setting mixer control: LINEOUT2 Volume, value: 0
08-15 21:17:47.966 179-460/? D/alsa_ucm: Setting mixer control: LINEOUT4 Volume, value: 0
08-15 21:17:47.966 179-460/? D/alsa_ucm: Setting mixer control: RX5 Digital Volume, value: 0
08-15 21:17:48.286 24660-24660/com.walintukai.heatmapdemo D/RecordingService: Tick: 1000
08-15 21:17:48.296 731-824/? D/SensorService:   0.2 -0.0 11.0
08-15 21:17:48.647 731-824/? E/Sensors: accelHandler 0.162861 -0.044308 11.044633
08-15 21:17:48.727 179-24722/? E/mm-camera: poll type 1 returns 0
08-15 21:17:48.727 179-24723/? E/mm-camera: poll type 1 returns 0
08-15 21:17:48.727 179-24721/? E/mm-camera: poll type 1 returns 0
08-15 21:17:49.297 24660-24660/com.walintukai.heatmapdemo D/RecordingService: Tick: 0
08-15 21:17:49.297 24660-24660/com.walintukai.heatmapdemo D/RecordingService: Timer Finished
08-15 21:17:49.297 24660-24660/com.walintukai.heatmapdemo D/RecordingService: Finished recording
08-15 21:17:49.297 179-20689/? D/MPEG4Writer: Stopping Video track
08-15 21:17:49.808 170-170/? E/SMD: DCD ON
08-15 21:17:50.309 179-24742/? W/CameraSource: Timed out waiting for incoming camera video frames: 0 us
08-15 21:17:51.440 179-24720/? E/mm-camera: poll type 1 returns 0
08-15 21:17:51.570 179-24724/? E/mm-camera: poll type 0 returns 0
08-15 21:17:51.800 731-824/? D/SensorService:   0.2 -0.0 11.1
08-15 21:17:52.111 731-856/? V/AlarmManager: waitForAlarm result :4
08-15 21:17:52.121 731-856/? V/AlarmManager: trigger ELAPSED_REALTIME_WAKEUP or RTC_WAKEUP
08-15 21:17:52.151 731-824/? E/Sensors: accelHandler 0.129331 -0.021555 11.078163
08-15 21:17:52.151 19505-24874/? I/Finsky: [3562] com.google.android.finsky.receivers.FlushLogsReceiver$FlushLogsService.onHandleIntent(163): Flushing event logs for [wwRg65ZPhINg_7-olzSHzcWExtM]
08-15 21:17:52.161 19505-19520/? I/PlayCommon: [3510] com.google.android.play.a.al.e(730): Preparing logs for uploading
08-15 21:17:52.161 19505-20595/? I/PlayCommon: [3552] com.google.android.play.a.w.a(27553): Starting to flush logs
08-15 21:17:52.161 19505-20595/? I/PlayCommon: [3552] com.google.android.play.a.w.a(27564): Log flushed by 0 successful uploads
08-15 21:17:52.201 1184-1184/? I/Auth: [AuthDelegateWrapper] Service intent: Intent { cmp=com.google.android.gms/.auth.account.authenticator.DefaultAuthDelegateService }.
08-15 21:17:52.201 1184-1184/? I/Auth: [AuthDelegateWrapper] Service intent: Intent { cmp=com.google.android.gms/.auth.account.authenticator.DefaultAuthDelegateService }.
08-15 21:17:52.261 19505-19520/? I/PlayCommon: [3510] com.google.android.play.a.al.a(870): Connecting to server: https://play.googleapis.com/play/log?format=raw&proto_v2=true
08-15 21:17:52.441 731-826/? W/ProcessCpuTracker: Skipping unknown process pid 24877
08-15 21:17:52.451 731-826/? W/ProcessCpuTracker: Skipping unknown process pid 24879
08-15 21:17:52.451 731-826/? W/ProcessCpuTracker: Skipping unknown process pid 24880

【问题讨论】:

  • 尝试在catch中添加RuntimeException并移动releaseMediaRecorder();等最终阻止。如果它有效,我会写一个答案来解释它为什么有效。
  • Log.d(TAG, "Finished recording."); 发生但 nothing 之后?有关这些的更多信息:logcat 对 try/catch 中的 e.printStackTrace(); 说了什么,我注意到您正在检查 != null,您可以输入日志以查看它们是否为 ==null
  • @NikoYuwono 添加了RuntimeException,但是两个catch块都没有被执行。我还将 releaseMediaRecorder() 移到 finally 块。
  • @TML 是的,完成的录制标签显示在日志中,mMediaRecorder.stop() 似乎在调试时被调用,但之后没有任何反应。 Log.d(TAG, "Media recorder stopped"); 不会显示在日志中,任何e.printStackTrace(); 调用也不会显示。
  • 你可以尝试添加通用异常捕获(异常 e){}

标签: java android mediarecorder android-mediarecorder


【解决方案1】:

鉴于跟踪代码执行的程度以及它(似乎)丢失的位置,我建议对您的代码进行以下修改,这应该可以让您更好地了解正在发生的事情。在“进入黑洞”之后看到整个堆栈跟踪会很有趣。

private void onFinishedRecording() {
    Log.d(TAG, "Going into the black hole.");
    try {
        Log.d(TAG, "So far so good, but if you don't see this just pull your hair ...");
        mMediaRecorder.stop();
        Log.d(TAG, "Media recorder stopped.");
    } catch (Error e) {
        Log.d(TAG, "So there was an error ...");
        e.printStackTrace();
        Log.d(TAG, "Did you get what that error was?");
    } catch (Exception e) {
        Log.d(TAG, "So there was some kind of an exception.");
        e.printStackTrace();
        Log.d(TAG, "Did you get what the exception was?");
    } finally {
        Log.d(TAG, "Leaving the black hole.");
    }
    Log.d(TAG, "So I did get out of the black hole after all ...");
    releaseMediaRecorder();
    releaseTimer();
    getSignedUrl();
}

祝你好运!

更新:

请包含原始 logcat 条目(不要将它们限制在您的应用中)。本机代码中的一些错误可能会导致看起来与您的应用程序无关的错误,但实际上它们可能是相关的。此外,请记住,预览大小必须与所选视频大小相同。详情请见this post

更新 2:

抱歉,我已经离开了,还没有机会深入了解。只是快速浏览了一下,我发现了一个关于相机超时的参考:

08-15 21:17:49.297 24660-24660/com.walintukai.heatmapdemo D/RecordingService: Finished recording
08-15 21:17:49.297 179-20689/? D/MPEG4Writer: Stopping Video track
08-15 21:17:49.808 170-170/? E/SMD: DCD ON
08-15 21:17:50.309 179-24742/? W/CameraSource: Timed out waiting for incoming camera video frames: 0 us

据我所知,在发出 stop() 之后,试图停止视频,但它仍然在 Stopping 并且永远不会到达 Stopped然后几行之后 CameraSource 超时。您可能需要添加更多日志条目,以查看在准备和开始录制之后发生的情况。那里可能有一些线索。似乎 stop() 调用以某种方式无限期地等待某些东西,例如相机(死锁)。这与没有任何错误的迹象是一致的,但之后没有其他任何事情发生。在此处放置一个断点并检查各种资源(特别是相机)的状态,看看它是否被锁定或处于导致 stop() 等待的状态。最后,我将验证预览是否使用支持的大小/分辨率,并确保它与您的录制大小和分辨率兼容。潜在的问题/不一致可能是内部死锁的原因(或任何阻止停止执行的原因。)

【讨论】:

  • 所以我添加了所有这些日志,这是结果08-14 18:35:57.788 14089-14089/com.walintukai.heatmapdemo D/RecordingService: Going into the black hole. 08-14 18:35:57.788 14089-14089/com.walintukai.heatmapdemo D/RecordingService: So far so good, but if you don't see this just pull your hair ...
  • 和之前的结果差不多。代码在尝试停止 MediaRecorder 时停止。
  • 您能否在最后一行之后再添加一些 logcat 条目,即使/如果它们似乎与您的应用无关?
  • 我已经包含了完整电话堆栈跟踪的很大一部分。我本来会包含更多,但我达到了帖子的字符数限制。
  • 在我的 logcat 中发现什么异常?
【解决方案2】:

嗯,我已经遇到过类似的情况,一些本机代码会崩溃并销毁当前线程,不说什么也不返回 Java 代码。

但因为它不是主线程,所以应用程序的其余部分似乎都很好。

也许 android 设备监视器会显示一些关于运行线程的重要信息。

希望这很有用。

【讨论】:

  • 好的,我稍后会测试这个!这听起来像是可能发生的事情。虽然,我在某些方法执行之前注销了哪个线程,它们都显示在主线程上。
  • 欢迎来到Stack Overflow!虽然您的贡献可能很有价值,但这是评论,而不是答案。您可以在任何地方发表 50 次代表的评论,而且您就快到了。坚持你现在可以直接回答的问题。
【解决方案3】:

我认为你应该在调用stop() 之前检查mediaRecorder 不是null

【讨论】:

  • 此时绝对不为空。一方面,它会在我的Exception e catch 块中抛出一个NullPointerException,它不会抛出任何东西。另外,我已经调试过了,此时MediaRecorder 不为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-31
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多