Android应用程序在主线程

时间:2018-04-24 14:32:41

标签: android

我在点击按钮时调用函数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帧!应用程序可能在其主线程上做了太多工作。

我需要更改功能中的任何内容吗? 帮我解决这个问题

2 个答案:

答案 0 :(得分:2)

您需要确保processImage方法在后台(非ui)线程上运行。它现在可能正在UI线程上运行,并且您会收到警告,因为它阻止了UI线程。

有许多方法可以在后台线程上工作,从简单地生成新线程到创建服务 - 您需要对此进行研究,并根据您的具体情况确定最佳方法。请记住,当后台处理完成后,您需要将数据传输到UI线程,并从UI线程更新UI,因为尝试从另一个线程更新将导致崩溃。

我唯一的具体建议是使用AsyncTask。它们在理论上听起来很棒,但除非你真的知道它们是如何工作的,否则它们会给你带来很多麻烦。如果你真的知道它们是如何工作的,那么你完全有能力做一些更可靠的事情。

答案 1 :(得分:0)

发布的代码在哪里?

通常,即使在UI线程上进行了艰苦的工作,屏幕也会冻结/断断续续,但最终会产生所需的输出。我估计86个跳帧是冻结的〜1.25秒。

  • 如果您的processImage()方法位于RunnableCallable<>等内,则可以了解Activity.runOnUiThread()的用法,但.. < / p>

  • 由于您收到此消息,而您没有提及此重要细节,因此我假设您的代码在UI线程上运行。

图像处理是一项昂贵的任务,应该在后台线程上执行。

要做一种背景工作,你应该使用一些现成的类(例如AsyncTaskService等),或者自己创建一个(借助于Executor等等。

了解如何执行此操作here