我需要继续运行一个线程,使用来自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 */
}
};
};
答案 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.将数据写入缓存文件以进行后处理。我已经为自己的应用做了这个。