1

I have the following button:

prStartBtn.setOnClickListener(new View.OnClickListener() {
        // @Override
        public void onClick(View v) {
            if (prRecordInProcess == false) {
                startRecording();
            } else {
                stopRecording();
            }
        }
    });

When i first press it, it does this:

private boolean startRecording() {
    prCamera.stopPreview();
    try {
        prCamera.unlock();
        prMediaRecorder.setCamera(prCamera);
        prMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        String lVideoFileFullPath;
        String lDisplayMsg = "Current container format: ";
        prMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); prMediaRecorder.setVideoEncoder(VideoEncoder.H264);
        if (first) {
            lVideoFileFullPath = cVideoFilePath + "result" + lVideoFileFullPath;
        } else {
            lVideoFileFullPath = cVideoFilePath + "vid2" + lVideoFileFullPath;
        }
        final File f = new File(lVideoFileFullPath);
        f.createNewFile();
        prRecordedFile = new FileOutputStream(f);
        prMediaRecorder.setOutputFile(prRecordedFile.getFD());
    prMediaRecorder.setVideoSize(sizeList.get(Utils.puResolutionChoice).width, sizeList.get(Utils.puResolutionChoice).height);
        prMediaRecorder.setVideoEncodingBitRate(3000000);
        prMediaRecorder.setVideoFrameRate(cFrameRate);
        prMediaRecorder.setPreviewDisplay(prSurfaceHolder.getSurface());
        prMediaRecorder.setMaxDuration(cMaxRecordDurationInMs);
        prMediaRecorder.setMaxFileSize(cMaxFileSizeInBytes);
        prMediaRecorder.prepare();
        prMediaRecorder.start();

        final Runnable r = new Runnable() {

            public void run() {
                try {
                    fileIn = new FileInputStream(f);
                    while (prRecordInProcess) {
                        // prRecordedFile.flush();
                        System.out.println("bytesAvailable: " + fileIn.available());
                        Thread.sleep(1000);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // handler.postDelayed(this, 1000);
            }
        };

        handler.postDelayed(r, 1000);
        prStartBtn.setText("Pause");
        prRecordInProcess = true;
        return true;
    } catch (IOException _le) {
        _le.printStackTrace();
        return false;
    }
}

Now if i comment out the runnable, the code works perfect. If i leave it, it runs (it shows me how the file grows), but i do not have access to the buttons anymore (if I press the button again, to stop recording, it does nothing), and after a while, it crashes (ANR). Any ideas how to fix this?

4

2 に答える 2

2

Runnable は UI スレッドで起動されます。そのため、UI がブロックされ、ANR が発生します。別のスレッドで起動するには、次のことができます。

Thread thread = new Thread()
{
@Override
public void run() {
    try {
        fileIn = new FileInputStream(f);
        while (prRecordInProcess) {
             // prRecordedFile.flush();
             System.out.println("bytesAvailable: " + fileIn.available());
             Thread.sleep(1000);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
};

thread.start();
于 2013-04-03T09:24:23.050 に答える
1

バックグラウンドで作業を実行し、完了したら UI に通知するAsyncTaskを使用します。

AsyncTasks は、理想的には短い操作 (せいぜい数秒) に使用する必要があります。スレッドを長時間実行し続ける必要がある場合は、次のような java.util.concurrent パッケージで提供されるさまざまな API を使用することを強くお勧めします。 Executor、ThreadPoolExecutor、および FutureTask。

于 2013-04-03T09:26:00.473 に答える