java.lang.RuntimeException:执行doInBackground()

时间:2019-01-29 11:44:50

标签: java android android-asynctask

我正在编程一个Android应用程序,并且在两个设备上我的应用程序因以下问题而崩溃:

更新:似乎存在一个问题,该问题与mediarecorder有关。现在我遇到了一个稍微不同的问题:

FATAL EXCEPTION: AsyncTask #3
Process: online.simpledesign.bikelog, PID: 14660
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:353)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:203)
    at android.os.Handler.<init>(Handler.java:117)
    at android.app.Dialog.<init>(Dialog.java:123)
    at android.app.Dialog.<init>(Dialog.java:168)
    at android.support.v7.app.AppCompatDialog.<init>(AppCompatDialog.java:46)
    at android.support.v7.app.AlertDialog.<init>(AlertDialog.java:97)
    at android.support.v7.app.AlertDialog$Builder.create(AlertDialog.java:980)
    at online.simpledesign.bikelog.Record$MediaPrepareTask.doInBackground(Record.java:539)
    at online.simpledesign.bikelog.Record$MediaPrepareTask.doInBackground(Record.java:524)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    ... 4 more

发生错误时执行的代码是:

class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {

    @Override
    protected Boolean doInBackground(Void... voids) {
        // initialize video camera
        if (prepareVideoRecorder()) {
            // Camera is available and unlocked, MediaRecorder is prepared,
            // now you can start recording

            mMediaRecorder.start();

        } else {
            // prepare didn't work, release the camera
            releaseMediaRecorder();
            //Rückmeldung: Kamera konnte nicht gestartet werden
            AlertDialog alertDialog = new AlertDialog.Builder(Record.this).create();
            alertDialog.setTitle("Achtung");
            alertDialog.setMessage("Kamera konnte nicht gestartet werden. Du kannst trotzdem die Daten aufzeichnen und mir so helfen.");
            alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Okay",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
            alertDialog.show();
            return false;
        }
        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        if (!result) {
            Record.this.finish();
        }

    }


}

我在这里尝试了所有解决方案,但没有一个起作用。更令我困惑的是,在某些设备上它可以正常工作。 装有Android 8.0的Xperia XZ1 Compact和装有Android 7.1的Google Pixel都会引发此问题。

任何建议都值得赞赏。

编辑:这是在prepareVideoRecorder中发生的事情:

private boolean prepareVideoRecorder() {

        // BEGIN_INCLUDE (configure_preview)
        mCamera = CameraHelper.getDefaultCameraInstance();
        if(CamcorderProfile.hasProfile(0,CamcorderProfile.QUALITY_QVGA)){

            // We need to make sure that our preview and recording video size are supported by the
            // camera. Query camera to find all the sizes and choose the optimal size given the
            // dimensions of our preview surface.
            Camera.Parameters parameters = mCamera.getParameters();
            List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
            List<Camera.Size> mSupportedVideoSizes = parameters.getSupportedVideoSizes();
            Camera.Size optimalSize = CameraHelper.getOptimalVideoSize(mSupportedVideoSizes, mSupportedPreviewSizes, mPreview.getWidth(), mPreview.getHeight());

            // Use the same size for recording profile.
            CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_QVGA);
            profile.videoFrameWidth = optimalSize.width;
            profile.videoFrameHeight = optimalSize.height;

            // likewise for the camera object itself.
            parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
            mCamera.setDisplayOrientation(90);
            mCamera.setParameters(parameters);
            try {
                // Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
                // with {@link SurfaceView}
                mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
            } catch (IOException e) {
                Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
                return false;
            }
            // END_INCLUDE (configure_preview)


            // BEGIN_INCLUDE (configure_media_recorder)
            mMediaRecorder = new MediaRecorder();

            // Step 1: Unlock and set camera to MediaRecorder
            mCamera.unlock();
            mMediaRecorder.setOrientationHint(90);
            mMediaRecorder.setCamera(mCamera);

            // Step 2: Set sources
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

            // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
            mMediaRecorder.setProfile(profile);
            mMediaRecorder.setVideoEncodingBitRate(1000000);
            // Step 4: Set output file
            mOutputFile = CameraHelper.getOutputMediaFile(getFilesDir().getAbsolutePath());
            if (mOutputFile == null) {
                return false;
            }
            mMediaRecorder.setOutputFile(mOutputFile.getPath());
            // END_INCLUDE (configure_media_recorder)

            // Step 5: Prepare configured MediaRecorder
            try {
                mMediaRecorder.prepare();
            } catch (IllegalStateException e) {
                Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
            } catch (IOException e) {
                Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
            }
            return true;
        }
        else {
            return false;
        }
    }

1 个答案:

答案 0 :(得分:0)

在方法prepareVideoRecorder()中,应首先检查是否支持要使用的配置文件-

if(CamcorderProfile.hasProfile()){
 // then get profile ....
}
  

public static boolean hasProfile(int cameraId,                   int quality);

如果它不支持,则总是会崩溃,因为该设备不支持该配置文件。因此,您需要先检查(如果仅受支持),然后再执行其余操作。