我在点击按钮时调用函数processImage()
,无法获得所需的确切输出。
processImage()
功能,
private void processImage() {
TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (textRecognizer.isOperational()) {
Log.d("IMAGE-PROCESS", "started");
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
final SparseArray<TextBlock> items = textRecognizer.detect(frame);
runOnUiThread(new Runnable(){
public void run() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
TextBlock textBlock = items.valueAt(i);
stringBuilder.append(textBlock.getValue());
stringBuilder.append("\n");
}
try {
Log.d("IMAGE-PROCESS", "finished");
Log.d("OUTPUT", stringBuilder.toString());
textView.setText(stringBuilder.toString());
} catch (final Exception ex) {
Log.i("EXC","Exception in thread");
}
}
});
} else {
Log.d("IMAGE-PROCESS", "not operational");
}
}
记录
I / Choreographer:跳过86帧!应用程序可能在其主线程上做了太多工作。
我需要更改功能中的任何内容吗? 帮我解决这个问题
答案 0 :(得分:2)
您需要确保processImage方法在后台(非ui)线程上运行。它现在可能正在UI线程上运行,并且您会收到警告,因为它阻止了UI线程。
有许多方法可以在后台线程上工作,从简单地生成新线程到创建服务 - 您需要对此进行研究,并根据您的具体情况确定最佳方法。请记住,当后台处理完成后,您需要将数据传输到UI线程,并从UI线程更新UI,因为尝试从另一个线程更新将导致崩溃。
我唯一的具体建议是不使用AsyncTask。它们在理论上听起来很棒,但除非你真的知道它们是如何工作的,否则它们会给你带来很多麻烦。如果你真的知道它们是如何工作的,那么你完全有能力做一些更可靠的事情。
答案 1 :(得分:0)
发布的代码在哪里?
通常,即使在UI线程上进行了艰苦的工作,屏幕也会冻结/断断续续,但最终会产生所需的输出。我估计86个跳帧是冻结的〜1.25秒。
如果您的processImage()
方法位于Runnable
,Callable<>
等内,则可以了解Activity.runOnUiThread()
的用法,但.. < / p>
由于您收到此消息,而您没有提及此重要细节,因此我假设您的代码在UI线程上运行。
图像处理是一项昂贵的任务,应该在后台线程上执行。
要做一种背景工作,你应该使用一些现成的类(例如AsyncTask
,Service
等),或者自己创建一个(借助于Executor
等等。
了解如何执行此操作here