温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

【移动开发】Android中异步加载数据(一)Handler + Thread

发布时间:2020-06-17 20:37:51 来源:网络 阅读:7905 作者:zhf651555765 栏目:开发技术

   在我们开发当中很多时候都会遇到:从网络上获取数据的操作或大量的IO数据操作时,会耗费很长时间,为了使用户的体验效果更好,现在大多数开发者都会使用异步的方式去处理这些的操作,异步的方式有好多种,在此我汇总了以下两种:

       1.Handler + Thread的方式

       2.AsyncTask异步更新UI界面

   这两种方式各自有各自的优缺点,这里先介绍一下第一种方式


1.Hanlder介绍:

   官方文档:

 A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

    一个处理程序允许你发送和处理消息或者Runnable对象关联到的一个线程的MessageQueue。每个处理程序的实例相关联着一个单个线程和一个线程的消息队列。当你创建一个新的处理程序,它被绑定到线程/消息队列的线程时创建它——从那时起,它将提供消息和runnables给消息队列和执行他们出来的消息队列。

   Handler主要方法:

               常用方法                 解释
Message obtainMessage(int what, Object obj)获取一个Message对象,包含了一个标识和value
boolean post(Runnable r)将Runnable r添加到消息队列,之后会被UI线程执行
boolean postDelayed(Runnable r, long delayMillis)延迟多少毫秒之后,再将该线程加入到消息队列中
boolean sendEmptyMessage(int what)发送一个只有标识的消息
boolean sendMessage(Message msg)添加一条消息到消息队列的末尾
void handleMessage(Message msg)用于处理接收到的消息


   简单的说Android采用UI单线程模型,所以只能在主线程中对UI元素进行操作。如果在非UI线程直接对UI进行了操作,就会报错,当然为了提高效率,Android为我们提供了消息循环的机制,我们可以利用这个机制来实现线程间的通信,在非UI线程发送消息到UI线程,最终让Ui线程来进行ui的操作


2.在非UI线程中发送消息通知UI线程更新界面:

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
 * Handler + Thread 实现异步加载图片
 * @author ZHF
 *
 */
public class MainActivity extends Activity {
    private static final int MSG_SUCCESS = 0;//成功获取图片
    private static final int MSG_FAILURE = 1;//获取图片失败
    public static final String IMG_URL = "http://p_w_picpaths.51cto.com/p_w_picpaths/index/Images/Logo.gi";
                                                                                                                                                                                                                                                                                                                                                                                                                                              
    Button btn_handler;
    ImageView p_w_picpathView;
                                                                                                                                                                                                                                                                                                                                                                                                                                              
    private DownloadImgThread downloadImgThread;
                                                                                                                                                                                                                                                                                                                                                                                                                                              
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg) { //该方法是在UI主线程中执行
            switch(msg.what) {
            case MSG_SUCCESS:
                p_w_picpathView.setImageBitmap((Bitmap)msg.obj);  //显示图片
                break;
            case MSG_FAILURE:
                Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_LONG);
                break;
            }
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                                                                                                                                                                                                                                                                                                                                                                                                                                                  
        p_w_picpathView = (ImageView) this.findViewById(R.id.p_w_picpathView);
                                                                                                                                                                                                                                                                                                                                                                                                                                                  
        btn_handler = (Button) this.findViewById(R.id.btn_handler);
        btn_handler.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //开启一个非UI线程,用于下载图片
                downloadImgThread = new DownloadImgThread();
                downloadImgThread.start();
            }
        });
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                              
    /**图片下载线程**/
    private class DownloadImgThread extends Thread{
        HttpURLConnection conn;
        InputStream inputStream;
        Bitmap imgBitmap;
                                                                                                                                                                                                                                                                                                                                                                                                                                                  
        @Override
        public void run() {
            try {
                URL url = new URL(IMG_URL);
                if(url != null) {
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(2000);
                    connection.setDoInput(true);
                    connection.setRequestMethod("GET");
                    int code = connection.getResponseCode();
                    if(200 == code) {
                        inputStream = connection.getInputStream();
                        imgBitmap = BitmapFactory.decodeStream(inputStream);
                        //获取图片成功,向ui线程发送MSG_SUCCESS标识和bitmap对象
                        mHandler.obtainMessage(MSG_SUCCESS,imgBitmap).sendToTarget();
                    }else {
                        //获取图片失败,向ui线程发送MSG_FAILURE
                        mHandler.obtainMessage(MSG_FAILURE).sendToTarget();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                              
}

在自己的线程中获取到imgBitmap,不能直接p_w_picpathView.setImageBitmap(imgBitmap),会报错的哦! 通过Message中obj将其存储起来,传递到UI线程中再对其操作。

权限:

<uses-permission android:name="android.permission.INTERNET"/>



2.View的post(Runnable r)方法

   在获取到imgBitmap之后,可以通过下面代码实现UI界面的更新哦:

//另外一种更简洁的发送消息给ui线程的方法。  
mImageView.post(new Runnable() {
         @Override  
        public void run() {//run()方法会在ui线程执行  
            mImageView.setImageBitmap(bm);  
         }  
     });

这是为什么那?

   因为Android框架为每个应用的主线程创建了一个隐式的handler,使用post方法的原理就是给这个隐式的handler发送一个Runnable对象,然后隐式的handler会在ui线程执行Runnable对象的run()方法。


下一篇(AsyncTask):http://smallwoniu.blog.51cto.com/3911954/1252156


附件:http://down.51cto.com/data/2363167
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI