详解android异步更新UI的几种方法
发布时间 - 2026-01-11 01:55:45 点击率:次前言

我们知道在Android开发中不能在非ui线程中更新ui,但是,有的时候我们需要在代码中执行一些诸如访问网络、查询数据库等耗时操作,为了不阻塞ui线程,我们时常会开启一个新的线程(工作线程)来执行这些耗时操作,然后我们可能需要将查询到的数据渲染到ui组件上,那么这个时候我们就需要考虑异步更新ui的问题了。
android中有下列几种异步更新ui的解决办法:
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
- long) View.postDelayed(Runnable, long)
- 使用handler(线程间通讯)(推荐)
- AsyncTask(推荐)
对于下面这段代码:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(bitmap);
}
}).start();
}
这段代码是一个按钮点击事件的响应方法,当点击了这个按钮后开启了一个子线程去网络上加载图片,然后在这个线程中给imageView设置了图片(更新了ui),这段代码在非ui线程中更新了ui,运行会引发错误。
1. Activity.runOnUiThread:
通常,在Activity,我们可以使用Activity的runOnUiThread方法来更新ui。
如:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
runOnUiThread(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
2. View.post(Runable)
View类及其子类提供了一个post(Runable)方法允许我们将我们要做的操作放到这个匿名Runable对象的run方法中,在这个方法里面我们可以直接更新ui。
如:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
imageView.post(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
3. long) View.postDelayed(Runnable, long)
和View.post(Runable)方法一样,只是延迟第二个参数指定的时间后执行,而View.post(Runable)是立即执行。
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
imageView.postDelayed(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(bitmap);
}
},2000);
}
}).start();
}
4. 使用Handler(推荐)
前面说道的几种方法当这种操作过多的时候,我们的代码会显得臃肿,代码及业务都难于管理控制,所以,当这类代码多的时候我们就应该采取Handler的方式了。
如:
new Thread(new Runnable() {
public void run() {
Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
Message message = mHandler.obtainMessage();
message.what = 1;
message.obj = bitmap;
mHandler.sendMessage(message);
}
}).start();
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
Bitmap bitmap = (Bitmap) msg.obj;
imageView.setImageBitmap(bitmap);
break;
case 2:
// ...
break;
default:
break;
}
}
};
5. AsyncTask(推荐)
android为我们提供了异步任务AsyncTask,我们可以使用AsyncTask轻松地实现异步加载数据及更新ui。
如:
AsyncTask<String,Void,Bitmap> asyncTask = new AsyncTask<String, Void, Bitmap>() {
/**
* 即将要执行耗时任务时回调,这里可以做一些初始化操作
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 在后台执行耗时操作,其返回值将作为onPostExecute方法的参数
* @param params
* @return
*/
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = loadImageFromNetwork(params[0]);
return bitmap;
}
/**
* 当这个异步任务执行完成后,也就是doInBackground()方法完成后,
* 其方法的返回结果就是这里的参数
* @param bitmap
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}
};
asyncTask.execute("http://example.com/image.png");
需要知道的是doInBackground方法工作在工作线程中,所以,我们在这个方法里面执行耗时操作。同时,由于其返回结果会传递到onPostExecute方法中,而onPostExecute方法工作在UI线程,这样我们就在这个方法里面更新ui,达到了异步更新ui的目的。
事实上,对于android的异步加载数据及更新ui,我们不仅可以选择AsyncTask异步任务,还可以选择许多开源的网络框架,如xUtils,Volley,Okhttp,…,这些优秀的网络框架让我们异步更新ui变得非常简单,而且,效率和性能也非常高。
总结:
对于上面的许多解决办法,其实它们做的都是同一件事情,即在工作线程中执行耗时任务,然后在ui线程中更新ui,只不过过程不一样,有得直接给我们封装好了,有得需要我们自己控制管理。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android异步更新UI
# android异步UI
# 详解android进行异步更新UI的四种方式
# Android异步更新UI的四种方式
# android开发教程之handler异步更新ui
# 在这个
# 这段
# 加载
# 可以使用
# 解决办法
# 有得
# 的是
# 都是
# 是一个
# 完成后
# 好了
# 就在
# 还可以
# 让我们
# 子类
# 中有
# 给我们
# 能在
# 我们可以
# 这类
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Android中AutoCompleteTextView自动提示
详解jQuery中的事件
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
教你用AI将一段旋律扩展成一首完整的曲子
Laravel怎么调用外部API_Laravel Http Client客户端使用
简单实现Android文件上传
Laravel如何使用Collections进行数据处理?(实用方法示例)
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
如何在万网自助建站中设置域名及备案?
Laravel如何使用Livewire构建动态组件?(入门代码)
ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
如何用PHP工具快速搭建高效网站?
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
如何在景安云服务器上绑定域名并配置虚拟主机?
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】
iOS验证手机号的正则表达式
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
使用Dockerfile构建java web环境
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
LinuxShell函数封装方法_脚本复用设计思路【教程】
青岛网站建设如何选择本地服务器?
在线教育网站制作平台,山西立德教育官网?
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
如何基于PHP生成高效IDC网络公司建站源码?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
英语简历制作免费网站推荐,如何将简历翻译成英文?
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
Laravel如何使用Telescope进行调试?(安装和使用教程)
微信小程序 scroll-view组件实现列表页实例代码
Python图片处理进阶教程_Pillow滤镜与图像增强
Laravel如何优化应用性能?(缓存和优化命令)
香港服务器网站卡顿?如何解决网络延迟与负载问题?
如何用AI帮你把自己的生活经历写成一个有趣的故事?
什么是JavaScript解构赋值_解构赋值有哪些实用技巧
消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
重庆市网站制作公司,重庆招聘网站哪个好?
高端云建站费用究竟需要多少预算?
JavaScript如何实现音频处理_Web Audio API如何工作?
Laravel如何实现事件和监听器?(Event & Listener实战)
香港服务器WordPress建站指南:SEO优化与高效部署策略
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
C++用Dijkstra(迪杰斯特拉)算法求最短路径
简历在线制作网站免费版,如何创建个人简历?
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法

