使用线程的滞后应用程序出现问题

时间:2011-01-31 15:26:42

标签: java android multithreading

这是我的理解(请纠正我,如果我不在标记)我正确使用线程将允许应用程序看起来多处理,尽管处理器负载很高。

在我的应用程序中,我有一个线程,我处理从相机预览中拍摄的图像,并尝试进行实时的人脸检测,取得了很大的成功。问题在于,与此同时,我希望能够在屏幕上显示一个可以按下的按钮,并且可以采取一些操作,而不考虑相机检测方法的内容。

问题是面部检测非常快,但是当我按下按钮时,需要大约一秒左右的时间才能响应。如果没有激活面部检测线程(即永远不会调用start()方法),则按钮非常快。下面是我的代码的剥离版本,因为它太长,只是直接发布:

public void surfaceCreated(SurfaceHolder holder) {
        mCamera = Camera.open();
        faceThread = new Thread(new Runnable(){
            public void run(){
                //Get camera preview image and detect faces
            }
        });
        faceThread.start();
    }

public void onClickShoot(View v) throws InterruptedException,
            media = new MediaPlayer();
    media.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        public void onCompletion(MediaPlayer mp) {
            media.stop();
            media.reset();
        }
    });
    media.setDataSource(this, dataPath);
    media.prepare();
    media.start();
            //And some other stuff here too.

    }

这是一个限制,我有这个延迟的事实,它是一个移动平台,我期待太多?或者有没有办法使这项工作?如果您需要更多关于我正在做什么的信息,请问:)。

编辑(解决问题的代码更多):

mCamera.setPreviewCallback(new PreviewCallback() {
                    public void onPreviewFrame(final byte[] _data, Camera _camera) {
                        Camera.Parameters parameters = mCamera.getParameters();
                        int format = parameters.getPreviewFormat();
                        // YUV formats require more conversion
                        if (format == ImageFormat.NV21) {
                            int w = parameters.getPreviewSize().width;
                            int h = parameters.getPreviewSize().height;
                            // Get the YuV image
                            YuvImage yuv_image = new YuvImage(_data, format, w, h, null);
                            // Convert YuV to Jpeg
                            Rect rect = new Rect(0, 0, w/3, h); // Rect of the image in which to search for the face
                            final ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
                            yuv_image.compressToJpeg(rect, 10, output_stream);
                            // Convert from Jpeg to Bitmap
                            detectFaces(BitmapFactory.decodeByteArray(
                                    output_stream.toByteArray(), 0,
                                    output_stream.size()));
                            Log.v("TEST", "TEST");
                        }
                    }
                });


public void detectFaces(Bitmap bmp) {
        FaceView faceView = new FaceView(this, bmp);
}

1 个答案:

答案 0 :(得分:3)

您需要确定争用的位置。是CPU时间,还是其他资源?这可能有助于进行一些分析...... Tim Bray最近在这里写了一个很好的介绍如何以及为什么这样做:http://android-developers.blogspot.com/2010/10/traceview-war-story.html

它的价值MediaPlayer是众所周知的缓慢和重量级。你给的是什么媒体?你是在为它提供一个主要在内存中的流或缓冲区,还是会通过网络或存储来读取大量的I / O?

出于兴趣,为什么按下按钮后需要进行面部检测?也许你可以在启动媒体播放器之前停止线程?