使用后台线程更新 UI 时出现问题
Problem with updating UI with background thread
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
// a potentially time consuming task
final Bitmap bitmap =
processBitMap("image.png");
imageView.post(new Runnable() {
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
我在 android 开发人员网站上阅读了这段代码,他们提到 后台操作是从一个单独的线程完成的,而 ImageView 始终是从 UI 线程操作的。 但是我不明白怎么办。谁能解释一下。
您需要从主线程更新 UI。为此,您可以使用下面的代码片段..
runOnUiThread(new Runnable(){
@Override
public void run(){
// update UI elements here
}
});
这不仅仅是图像视图。
每个应用程序都有自己的特殊线程,运行s UI 对象,例如 View 对象;此线程称为 UI 线程。只有 UI 线程上的对象 运行ning 才能访问该线程上的其他对象。因为您 运行 在线程池中的线程上执行的任务不会 运行 在您的 UI 线程上执行,所以它们无权访问 UI 对象。要将数据从后台线程移动到 UI 线程,请使用 运行 在 UI 线程上运行的处理程序或协程。
例如,看这段代码
GlobalScope.launch(Dispatchers.Main) { //IN THE MAIN THREAD
var x = withContext(Dispatchers.IO) { // in IO THREAD
wait() //BACKGROUND WORK
}
time.text = x //setting text to text view in main thread not IO or any
//other thread
}
Background operation is done from a separate thread while the
ImageView is always manipulated from the UI thread.
Android
应用程序中的所有 UI 元素都在 Main thread
中工作,通常表示 UI Thread
。如果您尝试在主线程下执行 long-运行ning 操作,它将冻结或 Application not 运行ning 异常将出现。所以你应该在后台线程下进行网络或数据库操作,并更新UI Thread
中的ImageView等UI元素。
UI 话题 :
启动应用程序时,Ui线程会自动创建
它负责将事件分派到适当的小部件
这包括绘画活动。
它也是您与 Android 小部件交互的线程
可运行:
表示可以执行的命令。通常用于 运行 在不同线程中编写代码。
后台运行
new Thread(new Runnable() {
public void run() {
// here the background operation happening
}
}).start();
View.post(Runnable)
用于从后台线程访问 UI 线程。
imageView.post(new Runnable() {
public void run() {
imageView.setImageBitmap(bitmap);
}
});
实际上,在大多数情况下,所有视图都是在 UI 或主线程中操作或处理的,另一个线程 a.k.a。 “后台线程”用于网络访问或数据库等长时间操作,以避免主线程被 UI 事件阻塞,用户会感觉到应用程序正在崩溃,因为屏幕将停止移动。
阅读以下文档了解更多信息:
https://developer.android.com/guide/components/processes-and-threads
毫无疑问,您应该在 java 中为繁重的进程使用不同的线程。但是,任何与 UI 相关的更改、初始化(如视图)、动画都应在使用您的应用程序创建的 UI(主)线程中完成。
你也可以这样做:
new Thread(new Runnable() {
@Override
public void run() {
final Bitmap bitmap =
processBitMap("image.png");
new Handler.post(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
即使您在另一个线程中执行后台作业,Handler
保证,设置图像也会在 UI/Main 线程中完成。
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
// a potentially time consuming task
final Bitmap bitmap =
processBitMap("image.png");
imageView.post(new Runnable() {
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
我在 android 开发人员网站上阅读了这段代码,他们提到 后台操作是从一个单独的线程完成的,而 ImageView 始终是从 UI 线程操作的。 但是我不明白怎么办。谁能解释一下。
您需要从主线程更新 UI。为此,您可以使用下面的代码片段..
runOnUiThread(new Runnable(){
@Override
public void run(){
// update UI elements here
}
});
这不仅仅是图像视图。
每个应用程序都有自己的特殊线程,运行s UI 对象,例如 View 对象;此线程称为 UI 线程。只有 UI 线程上的对象 运行ning 才能访问该线程上的其他对象。因为您 运行 在线程池中的线程上执行的任务不会 运行 在您的 UI 线程上执行,所以它们无权访问 UI 对象。要将数据从后台线程移动到 UI 线程,请使用 运行 在 UI 线程上运行的处理程序或协程。
例如,看这段代码
GlobalScope.launch(Dispatchers.Main) { //IN THE MAIN THREAD
var x = withContext(Dispatchers.IO) { // in IO THREAD
wait() //BACKGROUND WORK
}
time.text = x //setting text to text view in main thread not IO or any
//other thread
}
Background operation is done from a separate thread while the ImageView is always manipulated from the UI thread.
Android
应用程序中的所有 UI 元素都在 Main thread
中工作,通常表示 UI Thread
。如果您尝试在主线程下执行 long-运行ning 操作,它将冻结或 Application not 运行ning 异常将出现。所以你应该在后台线程下进行网络或数据库操作,并更新UI Thread
中的ImageView等UI元素。
UI 话题 :
启动应用程序时,Ui线程会自动创建
它负责将事件分派到适当的小部件 这包括绘画活动。
它也是您与 Android 小部件交互的线程
可运行: 表示可以执行的命令。通常用于 运行 在不同线程中编写代码。
后台运行
new Thread(new Runnable() {
public void run() {
// here the background operation happening
}
}).start();
View.post(Runnable)
用于从后台线程访问 UI 线程。
imageView.post(new Runnable() {
public void run() {
imageView.setImageBitmap(bitmap);
}
});
实际上,在大多数情况下,所有视图都是在 UI 或主线程中操作或处理的,另一个线程 a.k.a。 “后台线程”用于网络访问或数据库等长时间操作,以避免主线程被 UI 事件阻塞,用户会感觉到应用程序正在崩溃,因为屏幕将停止移动。
阅读以下文档了解更多信息: https://developer.android.com/guide/components/processes-and-threads
毫无疑问,您应该在 java 中为繁重的进程使用不同的线程。但是,任何与 UI 相关的更改、初始化(如视图)、动画都应在使用您的应用程序创建的 UI(主)线程中完成。
你也可以这样做:
new Thread(new Runnable() {
@Override
public void run() {
final Bitmap bitmap =
processBitMap("image.png");
new Handler.post(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
即使您在另一个线程中执行后台作业,Handler
保证,设置图像也会在 UI/Main 线程中完成。