网络编程代码重用的一点问题与技巧
来源:互联网 发布:淘宝运费险如何设置 编辑:程序博客网 时间:2024/06/06 02:00
网络编程代码重用的一点问题与技巧
基本的重用代码事例
学习android开发时大家都会接触到发起http请求的相关技巧,以及解析服务器返回的数据,应用程序可能会在多个地方都是用到网络功能,而发送http请求的代码都是非常相似的,于是理所当然地,我们应将这些操作整合到一起,比如一个工具类里。
public class HttpUtil{ public static String sendHttpRequest(String address) { HttpURLConnection connection = null; try { URL url = new URL(address); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader((new InputStreamReader(in))); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null){ response.append(line); } return response.toString(); } catch (Exception e){ e.printStackTrace(); } finally { if (reader != null){ try { reader.close(); } catch (IOException e){ e.printStackTrace(); } } if (connection != null){ connection.disconnect(); } } }}
这样我们只需要传入网址,获取服务器相应的数据后,就可以进行后续的解析和处理了。
String address = "http://blog.dota2.com/"String response = HttpUtil.sendHttpRequest(address);
线程是个问题
网络请求通常都是耗时的操作,而我们的sendHtttpRequest()方法内部并没有开启线程,这样可能会使主线程被阻塞住,这对用户的体验有不好的影响。
但我们恐怕也不能简单地在sendHtttpRequest()方法开启一个线程来解决问题。因为所有的耗时逻辑都在子线程进行的,sendHtttpRequest()方法会在服务器还没来得及响应的时候就执行结束了,导致该方法无法返回相应的数据。
所以我们需要另寻他路。
java的回调机制
我们先来看下面的代码:
public interface HttpCallBackListener { void onFinish(String response); void onError(Exception e);}
我们定义了一个接口并在其中定义了两个方法,onFinish()在服务器相应请求时调用,参数是服务器返回的数据,onError()在进行网络操作出现错误时调用,参数是错误的详细信息。
然后修改HttpUtil的代码:
public class HttpUtil{ public static String sendHttpRequest(final String address, final HttpCallbackListener listener) { new Thread(new Runnable(){ @Override public void run() { HttpURLConnection connection = null; try { URL url = new URL(address); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader((new InputStreamReader(in))); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null){ response.append(line); } if (listener != null) { listener.onFinish(response.toString()); } } catch (Exception e){ if (listener != null) { listener.onError(e); } } finally { if (reader != null){ try { reader.close(); } catch (IOException e){ e.printStackTrace(); } } if (connection != null){ connection.disconnect(); } } } }).start; }}
我们给sendHttpRequest()方法添加了一个HttpCallbackListener参数,并在方法的内部开启了一个子线程,由子线程去执行网络操作。由于子线程无法通过return语句返回数据,因此我们将数据传入了HttpCallbackListener的onFinish()方法中,而异常传入了onError()方法中。
现在,调用sendHttpRequest()方法的代码是这样的:
HttpUtil.sendHttpRequest("http://blog.dota2.com/", new HttpCallbackListener() { @Override public void onFinish(String response) { // 根据返回的数据执行具体逻辑 } public void onError(Exception e) { // 在此处理异常 }});
如此一来,通过利用回调机制我们就解决了网络编程的线程问题。
使用OKHttp实现回调机制
有句话说得好,不要重复发明伦子,其实OKHttp已经提供了实现相同功能的接口,如下:
public static void sendOkHttpRequest(String address, okhttp3.Callback callback) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(address).build(); client.newCall(request).enqueue(callback);}
sendOkHttpRequest传入了一个okhttp3.Callback参数,这是OkHttp库中自带的一个回调接口,类似于刚才的HttpCallbackListener。在client.newCall()之后调用enqueue()方法,并把okhttp3.Callback参数传入,没错,OkHttp会在enqueue()方法内部自己开好子线程并执行http请求,最终将请求结果回调到okhttp3.Callback当中。
所以,现在我们调用sendOkHttpRequest()方法是这样写:
HttpUtil.sendOkHttpRequest("http://blog.dota2.com/", new okhttp3.Callback() { @Override public void onResponse(Call call, Response response) throws IOException { // 根据返回的数据执行具体逻辑 String responseData = response.body().string(); } public void onFailure(Call call, IOException e) { // 在此处理异常 }});
这样,我们只需编写少量的代码就能完成较为复杂的网络操作了。
- 网络编程代码重用的一点问题与技巧
- 组件使用的一点技巧(代码重用)
- java代码重用的一点思考
- php的代码重用与函数
- 编程技术以及代码重用
- 一点c++编程的小技巧
- Cell的重用代码
- c++的代码重用
- UITableViewCell的重用代码
- Cell的重用代码
- c++的代码重用
- 关于网络编程的一点困惑
- 对于C++网络编程的一点了解
- Linux C网络编程的一点总结
- play框架如何重用代码及发现的问题
- C++代码设计与重用
- 关于在网络编程是IP地址是否要带点发送的问题,自己的一点看法
- 代码重构-------ListView与GridView的适配器重用篇
- 聊聊设计模式(2):享元模式
- java集合框架、集合操作--线性表
- Android之Windows下搭建React Native Android开发环境
- call 和 apply的作用
- 网络攻防技术与实践笔记-信息收集技术手段
- 网络编程代码重用的一点问题与技巧
- 使用 MobX 开发 React Native 应用
- 7个原因:为什么要选择ArangoDB-原生多模型数据库?
- Makefile中的wildcard用法
- 并发队列-无界阻塞队列LinkedBlockingQueue原理探究
- Python3学习笔记-基本数据类型
- 五个唯独
- 机器学习实战-利用AdaBoost元算法提高分类性能
- 一键式弹出菜单