1

我需要继续运行一个线程,该线程使用来自android设备的相机的帧进行图像处理。

我试过最简单的方法

new Thread() {

    @Override
    public void run() {
        while (true) {
            /* Processing frames here */
        }
    }
}.start();

但这会过多地占用 CPU,并且 UI 开始滞后。此外,Thread.sleep(300)在处理帧之后添加,以便 UI 线程可以获得一些 CPU 时间,但尽管它确实在一定程度上有所帮助,但感觉不是正确的方法。

我想对处理这个问题的好方法有一些想法。

编辑:使用AsyncTask

private DetectionTask detectionTask;

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    /* Doing some stuff here */

    camera.addCallbackBuffer(data);

    if (detectionTask != null && detectionTask.getStatus() != AsyncTask.Status.FINISHED)
        return;

    detectionTask = new DetectionTask();
    detectionTask.execute();
}

private class DetectionTask extends AsyncTask<Void, Void, float[]> {

    @Override
    protected float[] doInBackground(Void... params) {
        /* Processing frames here */
        return result;
    }

    @Override
    protected void onPostExecute(float[] result) {
        if (result != null) {
           /* Update UI */
        }
    };
};
4

4 回答 4

1

你考虑过AsyncTask吗?
它是专门为处理后台重负载而设计的。
它将在后台执行繁重的过程并在完成后更新您的 UI。

于 2013-09-26T04:31:34.740 回答
1

如果您确切知道何时准备好处理帧,则可以使用Object.wait()Object.notify()方法作为一种简单的机制来向处理器线程发出帧准备就绪的信号。

Object mLock = new Object();
Thread mProcessor = new Thread() {
    @Override
    public void run() {
        while (true) {
            mLock.wait();
            // do processing
        }
    }
};

然后mLock.notify()在准备好一帧或一批帧时调用。

于 2013-09-26T04:23:08.760 回答
1

考虑使用Service而不是Thread. 它是长时间运行进程的常用工具,这些进程必须不时在另一个线程上做一些工作。

于 2013-09-26T04:15:00.050 回答
0

通常我使用Thread. 如果您使用的是具有多核处理器的设备,系统会自动将线程分派到不同的内核。这意味着同时运行 UI 线程和助手线程将没有问题。通常,我将预览回调中的数据保存到内存中的缓冲区队列中,这不会阻塞 UI。然后创建另一个线程来读取和处理缓冲区中的数据。缓冲队列必须同步。如果您的数据处理需要太多时间,您有两种选择:1. 策略性地跳过一些帧 2. 将数据写入缓存文件以进行后期处理。我已经为我自己的应用程序做了这个。

于 2013-09-26T06:05:29.177 回答