在工作线程内创建视图

cdr*_*oid 16 multithreading android android-ui android-layout

我需要从EditText生成一个位图,然后对其执行一些操作.我主要担心的是不要View.buildDrawingCache()在UI线程上调用方法并且可能阻止它,特别是在谈论大屏幕(即Nexus 10)时,因为EditText它将占据可用屏幕大小的大约80%.

Runnable在一个内部执行s ThreadPoolExecutor,这将在工作线程上膨胀虚拟视图并为它们设置所有必需的属性,然后只需调用buildDrawingCache()&getDrawingCache()生成一个位图.

这在某些设备上运行良好但是最近我遇到了一些因以下消息而崩溃的设备:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Run Code Online (Sandbox Code Playgroud)

我理解为什么会这样,因为有些手机必须修改实施EditText,创建一个Handler,因此需要Looper.prepare()首先被调用.

从我在网上看到的内容,在工作线程中调用Looper.prepare()没有问题,虽然有人说这是非常不推荐但我找不到原因.

除此之外,与此问题相关的大多数帖子都表明您不应该在后台线程中夸大视图,可能是由于Android的官方文档(进程和线程)中的以下内容:

"Do not access the Android UI toolkit from outside the UI thread"
Run Code Online (Sandbox Code Playgroud)
  • 处理此问题的推荐方法是什么?

  • 从主线程调用build/get drawingcache有什么害处吗?(性能明智)

  • 在我的工作线程中调用Looper.prepare()会解决这个问题吗?

编辑

为了详细说明我的具体要求,我有一个用户界面,包括一个ImageView和一个自定义的EditText,EditText可以根据用户选择改变它的字体和颜色,它可以使用"放大/缩小".捏缩放"手势也可以拖动以允许用户将其重新定位在图像上方.

最后,我所做的是使用当前在UI上完全相同的值(宽度,高度,位置)在工作线程内创建一个虚拟视图,然后生成它的绘图缓存,原始图像的位图再次从本地文件解码.

一旦两个位图准备就绪,我将它们合并到一个位图中以备将来使用.

简单来说,执行以下代码(从后台线程中)有什么问题:

呼叫Looper.prepare()创建应用程序上下文一个新的观点,称measure()layout()手动,然后建立+从它那里得到drawingcache,即:

Looper.prepare();

EditText view = new EditText(appContext);

view.setText("some text");
view.setLayoutParams(layoutParams);

view.measure(
        View.MeasureSpec.makeMeasureSpec(targetWidth, View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(targetHeight, View.MeasureSpec.EXACTLY));

view.layout(0, 0, targetWidth, targetHeight);

view.buildDrawingCache();

Bitmap bitmap = view.getDrawingCache();
Run Code Online (Sandbox Code Playgroud)

如何在UI线程外部不访问Android UI工具包时适用于限制,可能出现什么问题?

Gom*_*ino 4

对于您的情况,您当然可以这样做,但要小心,仅从 UI 数据中读取值,以避免同步错误。

另外,您不应该从后台线程重新创建 EditText,直接访问已经存在的 EditText 会更有效:

Looper.prepare();
myEditText.setDrawingCacheEnabled(true);
Bitmap bitmap = myEditText.getDrawingCache();
Run Code Online (Sandbox Code Playgroud)

如果您的问题是:为什么 Android 指南不推荐它,这里有一个很好的答案来回答您的问题。