这里有新鲜出炉的精品教程,程序狗速度看过来!
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
本篇文章主要介绍了详解 android 异步更新 UI 的几种方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
前言
我们知道在 Android 开发中不能在非 ui 线程中更新 ui,但是,有的时候我们需要在代码中执行一些诸如访问网络、查询数据库等耗时操作,为了不阻塞 ui 线程,我们时常会开启一个新的线程(工作线程)来执行这些耗时操作,然后我们可能需要将查询到的数据渲染到 ui 组件上,那么这个时候我们就需要考虑异步更新 ui 的问题了。
android 中有下列几种异步更新 ui 的解决办法:
对于下面这段代码:
- 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,只不过过程不一样,有得直接给我们封装好了,有得需要我们自己控制管理。
来源: http://www.phperz.com/article/17/0703/336614.html