Handler实现对一个网页的异步加载,并将过程封装

本文介绍如何利用Handler实现对网页的异步加载,通过创建DownHTMLRunnable类封装数据获取过程,并使用Callback接口处理异步回调。在子线程中下载网络数据,然后在主线程中通过Message更新UI,确保UI操作的正确性。
摘要由CSDN通过智能技术生成

思路:

1.利用异步访问http://www.tngou.net/api/top/show?id=13122,建立连接,下载字符串,返回给主线程.
2.利用gson对字符串解析,封装成为实体对象.
3.利用回调函数将实体对象的内容填充到控件中.

实现:

创建一个类DownHTMLRunnable,对获取数据的过程进行封装,并且传递一个Callback以便对获取的数据进行操作,为了通用化,接口内部的参数使用泛型,实例化的时候传入自己需要的实体类类型
 public class DownHTMLRunnable<T> implements Runnable {
    private static final String TAG = DownHTMLRunnable.class.getSimpleName();
    private String url;
    private Class<T> tClass;
    private MyCallback callback;

    public DownHTMLRunnable(String url, MyCallback callback, Class<T> tClass) {
        this.url = url;
        this.callback = callback;
        this.tClass = tClass;
    }

    //定义一个内部接口,通过这个机构把Entry传递出去,这个接口其实可以写一个单独的文件,但是为了封装还是写在这里面比较好
    public interface MyCallback<S> {    //这里的泛型和T无关
        void onSuccess(S s);

        void onFail(Exception e);
    }
重写run方法,在子线程中下载网络数据并解析,通过message发送回主线程(只有run方法在子线程中执行)
 @Override
    public void run() {
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            int responseCode = connection.getResponseCode();
            if (responseCode == 200) {
                InputStream inputStream = connection.getInputStream();
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                int len;
                byte[] bytes = new byte[102400];
                while ((len = inputStream.read(bytes)) != -1) {
                    byteArrayOutputStream.write(bytes, 0, len);
                }
                String s = byteArrayOutputStream.toString("UTF-8");
                T t = new Gson().fromJson(s, tClass);
                Message message = handler.obtainMessage(0, t);
                message.sendToTarget();
            } else {
                Message message = handler.obtainMessage(1, new RuntimeException("网络错误,请检查网络"));
            }
        } catch (IOException e) {
            e.printStackTrace();
            Message message = handler.obtainMessage(1, e);
        }
    }
重新handler中的方法,对不同类型的message进行不同处理
private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    T t = (T) msg.obj;
                    Log.d(TAG, "handleMessage: " + t.toString());

                    //这里接收到了子线程返回的数据,现在要做的只是把数据返回给调用的Activity
                    //这里采用创建一个接口,讲获得的数据传入接口的参数中,当调用者使用的时候,必须实现接口,制定具体的处理方案
                    callback.onSuccess(t);
                    break;
                case 1:
                    Exception exception = (Exception) msg.obj;
                    callback.onFail(exception);
                    break;
            }
        }
    };
主Avtivity中:

实例化一个DownHTMLRunnable,并且重写onSuccess,onFail对数据进行处理,将数据填充到控件中,此时参数o,是从DownHTMLRunnable传出来的封装好的数据,我们只是对操作进行了重写

 DownHTMLRunnable<Entry> runnable = new DownHTMLRunnable<>(url, new DownHTMLRunnable.MyCallback() {
            @Override
            public void onSuccess(Object o) {
                Entry entry = (Entry) o;
                setTitle(entry.getTitle());
                String img_url = "http://tnfs.tngou.net/img"+entry.getImage();
                new Thread(new ImageLoaderRunnable(img_url,imageView)).start();
                String message = entry.getMessage();
                webview.loadDataWithBaseURL("http://www.tngou.net/api/top/show?id=12345",CSS+ message,"text/html;charset=utf-8","UTF-8",null);
                Toast.makeText(MainActivity.this, entry.getImage(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFail(Exception e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
            }
        },Entry.class);
        new Thread(runnable).start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值