在 android 中,ui 操作必须在主线程中进行,不能直接在子线程中更新 ui。今天介绍两种在子线程切换回主线程的方法。
runonuithread() 和 handler.post() 都可以用于切换到 主线程(ui 线程) 执行任务,主要用于 更新 ui。但它们在使用方式、作用范围、底层实现上有所不同。
1. runonuithread()
runonuithread() 是 activity 的一个方法,它可以让任务在 主线程(ui 线程) 执行。适用于 在 activity 内部 从子线程切换到主线程 以更新 ui。
用法:
runonuithread(new runnable() {
@override
public void run() {
textview.settext("更新 ui");
}
});
lambda 写法:
runonuithread(() -> textview.settext("更新 ui"));
底层原理:
runonuithread() 的实现本质上 使用了 handler.post(),它会获取 activity 绑定的 looper,然后将任务投递到 主线程消息队列。
适用场景
- 只在
activity里使用,不能在service、broadcastreceiver等组件中用。 - 简单的 ui 更新,比如在
oncreate()、网络请求回调、异步任务完成后 更新 textview、button 等 ui 组件。
完整的代码:实现的效果很简单,2秒后在主界面更新ui,显示 "ui 更新成功!"
public class mainactivity extends appcompatactivity {
private textview textview;
@suppresslint("missinginflatedid")
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main9);
textview = findviewbyid(r.id.textview);
// 在子线程中执行耗时操作
new thread(new runnable() {
@override
public void run() {
try {
thread.sleep(2000); // 模拟网络请求或其他耗时任务
} catch (interruptedexception e) {
e.printstacktrace();
}
// 切换到主线程更新 ui
runonuithread(new runnable() {
@override
public void run() {
textview.settext("ui 更新成功!");
}
});
}
}).start();
}
}2. handler.post()
handler.post() 通过 handler 将任务投递到指定的线程,一般用于 从子线程切换到主线程 处理 ui 更新,也可以用于子线程间通信。
handler handler = new handler(looper.getmainlooper());
handler.post(() -> textview.settext("更新 ui"));
底层原理
handler通过messagequeue投递任务,looper取出并执行。- 不会判断当前线程,即使
post()发生在主线程,它也会把任务加入消息队列,可能稍微延迟执行。
适用场景
- 适用于 所有 android 组件(
activity、service、fragment、broadcastreceiver)。 - 可以执行延迟任务(
postdelayed())。 - 可在子线程和子线程间通信,不仅限于 ui 更新。
完整代码,实现的效果和上面runonuithread()是一样的。2秒延迟后,主界面显示"数据加载完成"
import android.os.handler;
import android.os.looper;
public class mainactivity extends appcompatactivity {
private textview textview;
@suppresslint("missinginflatedid")
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main9);
textview = findviewbyid(r.id.textview);
handler handler = new handler(looper.getmainlooper());
new thread(() -> {
try {
thread.sleep(2000); // 模拟网络请求
} catch (interruptedexception e) {
e.printstacktrace();
}
handler.post(() -> textview.settext("数据加载完成"));
}).start();
}
}
到此这篇关于android studio切换主线程的两种方式详解的文章就介绍到这了,更多相关android studio切换主线程内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论