java - 使用线程的滞后应用程序的问题

标签 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);
}

最佳答案

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

就其值(value)而言,MediaPlayer 是出了名的缓慢且重量级。您提供什么媒体?您是否为它提供了一个主要位于内存中的流或缓冲区,或者它会执行大量 I/O 来通过网络或从存储读取媒体?

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

关于java - 使用线程的滞后应用程序的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4852612/

相关文章:

java - 如果未执行 JAXB 模型中的 setter,则不显示 XML 元素

java - 如何使用gwt在java中使用加密和解密来保存密码

Android 自定义 XML 解析器无法解析 android 命名空间

android - 在 Android 上实现益智游戏

java - 类似于java中的fork()函数

java - Java中信号量的实现

java - 如何从java中的溢出字节中删除(f)位

java - spring在redis中存储session的方法

Android 2.2 - SoundPool 示例 0 未就绪

java - Java 中的多线程音频