实现连续线程的有效方法

时间:2013-09-26 04:10:34

标签: java android multithreading performance android-asynctask

我需要继续运行一个线程,使用来自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 个答案:

答案 0 :(得分:1)

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

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

答案 2 :(得分:1)

您是否考虑过AsyncTask? 它专门设计用于处理背景中的重负荷 它将在后台执行繁重的过程并在完成后更新您的UI。

答案 3 :(得分:0)

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