View.getWidth()
希望这是一个关于和View.getHeight()
方法的线程安全的简单问题。
我正在编写一个后台任务,该任务执行给定 View 对象的操作。视图中唯一真正需要的部分是它的维度。但是,当我的任务启动时,视图可能没有经过布局过程,因此它的尺寸设置为 0。任务在 UI 上启动,但在返回到发布结果的 UI 线程(很像AsyncTask
)。
我想知道从后台线程调用这些 getter 方法会产生什么影响。我知道 UI 工具包被设计为单线程的,所以我担心我可能会冒着发布不安全出版物的风险。
Kcoppock 有一个很好的解决方案,当尺寸已知时,通过在 UI 线程上接收回调来避免这个问题。
我写了一个小测试来查看这些维度何时可以从后台线程(附在下面)中看到,并且似乎它们与回调同时可用。
当然,我知道这并不能证明任何事情,所以如果有人对 UI 框架有更深入的了解,我将不胜感激。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ImageView view = new ImageView(this);
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.d("TAG", Thread.currentThread().getName() + ": onGlobalLayout()");
Log.d("TAG", Thread.currentThread().getName() + ": view dimensions: " + view.getWidth() + "x" + view.getHeight());
}
});
// Bad code follows
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Log.d("TAG", Thread.currentThread().getName() + ": view dimensions: " + view.getWidth() + "x" + view.getHeight());
try {
Thread.sleep(1);
} catch (InterruptedException ignored) {}
}
}
}).start();
setContentView(view);
Log.v("TAG", "Set view as content");
}