启动可运行,我的按钮不再响应

时间:2013-04-03 09:15:35

标签: android multithreading handler

我有以下按钮:

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

当我第一次按它时,它会这样做:

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;
    }
}

现在,如果我注释掉runnable,代码就完美了。如果我离开它,它运行(它显示文件如何增长),但我不再能够访问按钮(如果我再次按下按钮,停止录制,它什么都不做),过了一会儿,它崩溃(ANR)。任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分: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();

答案 1 :(得分:1)

使用AsyncTask,它将在后台执行您的工作,并在完成后通知您的用户界面。

理想情况下,AsyncTasks应该用于短操作(最多几秒钟。)如果需要保持线程长时间运行,强烈建议您使用java提供的各种API。 util.concurrent pacakge,如Executor,ThreadPoolExecutor和FutureTask。