在后台Android中进行繁重处理时UI冻结
Posted
技术标签:
【中文标题】在后台Android中进行繁重处理时UI冻结【英文标题】:UI Freezing while doing heavy processing in background Android 【发布时间】:2019-07-03 09:19:53 【问题描述】:在 UI 线程上:
AsyncCaller asyncCaller = new AsyncCaller();
asyncCaller.doInBackground();
在异步任务中: @覆盖 protected Void doInBackground(Void... params)
Mat orignal = new Mat(image1.getHeight(), image1.getWidth(), CvType.CV_8UC3);
Mat v_blur = new Mat(image1.getHeight(), image1.getWidth(), CvType.CV_8UC3);
Utils.bitmapToMat(image1, orignal);
Imgproc.GaussianBlur(orignal, v_blur, new Size(3, 3), 0);
// blur completed
Mat to_zero = new Mat(image1.getHeight(), image1.getWidth(), CvType.CV_8UC4);
Imgproc.threshold(v_blur, to_zero, 100, 100, Imgproc.THRESH_TOZERO);
Bitmap bmp = image1;
Log.e("background", "in bg");
Utils.bitmapToMat(bmp, to_zero);
for (int j = 0; j < bmp.getWidth(); j++)
for (int i = 0; i < bmp.getHeight(); i++)
int pixelValue = bmp.getPixel(j, i);
int red = Color.red(pixelValue);
int green = Color.green(pixelValue);
int blue = Color.blue(pixelValue);
if (red > 10 && blue > 10 && green > 10)
int led_bulb = checkForAlreadyExistance(j, i);
if (led_bulb == -1)
int start_x = getMinValue(j);
int start_y = getMinValue(i);
int end_x = getMaxValue(j, bmp.getWidth());
int end_y = getMaxValue(i, bmp.getHeight());
Log.e("crop_values", start_x + " " + end_x + " " + start_y + " " + end_y);
LEDs.add(new LedBoundingBox(LED++, end_x, start_x, end_y, start_y, 0, 0, 0.0));
else
if (j > LEDs.get(led_bulb).inner_x_max)
LEDs.get(led_bulb).inner_x_max = j;
if (j < LEDs.get(led_bulb).inner_x_min)
LEDs.get(led_bulb).inner_x_min = j;
if (i > LEDs.get(led_bulb).inner_y_max)
LEDs.get(led_bulb).inner_y_max = i;
if (i < LEDs.get(led_bulb).inner_y_min)
LEDs.get(led_bulb).inner_y_min = i;
Log.e("bgComplete", "complete");
return null;
我正在使用 android OpenCV 库进行图像处理。首先,我在 UI 线程上完成了所有这些工作,但遇到了 UI 挂起问题。所以我把它转移到后台线程。但我仍然面临 UI 挂起问题。谁能解释为什么会发生这种情况以及任何可能的解决方案? 谢谢
【问题讨论】:
【参考方案1】:使用asyncCaller.execute():,不要直接调用doInBackground()
现在您在 UI 线程上调用此方法,而不是启动 AsyncTask 并让任务自行调用线程。
AsyncTask 任务 = new AsyncTask(); task.execute(paramsForDoInBackground);
应该怎么称呼
【讨论】:
非常感谢兄弟.. 像魅力一样工作:)。【参考方案2】:为您的工作使用 Java 线程而不是异步任务! 异步任务仅适用于小型操作。
请在此处查看: https://***.com/a/18480297/4632620
【讨论】:
感谢您的回复。让我试试这种线程方法,很快就会得到你的认可。 我尝试了这种方法,但在访问 UI 元素时出错。这可能是一个好方法,但就我而言,需要对以前的代码进行许多更改。我尝试了布兰登的答案,这对我有用,无需做任何更改。顺便说一句,感谢您的回复。 您可以通过 Handlers 和 Loppers 传递 UI 元素来访问它们。因为如果是主线程,则无法在外部更改 UI 元素。【参考方案3】:如果您不想冻结 UI,最简单、最好和直观的示例会演示它应该是怎样的。每个面临这个问题的人或不知道如何为 android 项目编写代码的人都应该看到并遵循这种风格:
Video Demonstration of Avoiding UI freezing
【讨论】:
以上是关于在后台Android中进行繁重处理时UI冻结的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用 WebAssembly 进行大量计算时保持反应式 UI?
使用 FirestoreDecoder 解码 Firestore 文档时 UI 冻结