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

来源:互联网 发布:114网络预约挂号 编辑:程序博客网 时间:2024/06/08 00:10

思路:

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();
0 0
原创粉丝点击