《第一行代码》读书笔记---发起HTTP请求的封装

一、HttpURLConnection

public class HttpUtil{
	public static String sendHttpRequest(String address){
		try{
			Url url=new Url(address);
			connection=(HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.setConnectionTimeout(8000);
			connection.setReadoutTimeout(8000);
			connection.setDoInput(true);//当属性时GET时,默认时true
			connection.setDoOutput(true);
			

> 如果想要获得输出流(例如,向一个Web服务器提交数据),必须将它设为true

			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();
			return e.getMessage();
		}finally{
			if(connection!=null){
				connection.disconnect();
			}
		}
	}
}

当发出一个HTTP请求的时候可以这样写:

String address="http://www.baidu.com";
String response=HttpUtil.sendHttpRequest(address);

这里存在一个问题:

  • 在UI线程不可以进行这样的耗时逻辑。

那么我们可以有几种解决方案:

  • 新开一个子线程实行这个方法(将这部分逻辑分离到子线程中,不知道可不可以)。
new Thread(new Runnable(){
	String address="http://www.baidu.com";
	String response=HttpUtil.sendHttpRequest(address);
}).start();
  • 在方法内部新开一个子线程

第二种方法有几个问题:

  • 在内部重写Runnable方法将会没有返回值,因为直接Thread#start(),不符合要求。
  • sendHttpRequest()方法会在服务器还没来得及响应的时候就执行结束了(假如A线程开启了B线程需要对象α,在1这个时间点需要这个数据,而此时B线程未得到这组数据,A线程就拿到对象α的默认值,并没有得到真实数据,所以B线程即使执行结束也是没有意义的。)

书上给了一种解决方案,即接口回调。(在接口类中进行处理得到的数据,分离部分逻辑)

  • 定义一个接口HttpCallBackListener
public interface HttpCallbackListener{
	void onFinish(String response);
	void onError(Exception e);
}
  • 接着修改工具类的代码
public class HttpUtil{
	public static String sendHttpRequest(final String address,final HttpCallbackListener listener){
	new Thread(new Runnable(){
		try{
			Url url=new Url(address);
			connection=(HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.setConnectionTimeout(8000);
			connection.setReadoutTimeout(8000);
			connection.setDoInput(true);//当属性时GET时,默认时true
			connection.setDoOutput(true);//不知道这个干嘛用,但是如果用POST的话,需要设置为true
			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)
			listen.onFinish(response.toString());
		}catch(Exception e){
			listener.onError(e);
		}finally{
			if(connection!=null){
				connection.disconnect();
			}
		}
	}).start();
	}
}

两种方法实际上是一样的,要注意的一点是两者都一直在子线程中运行,要进行UI操作还是要到主线程中进行操作。

二、OkHttp

public class HttpUtil{
	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);
}

okhttp3.Callback是自带的一个回调接口,可以重写其中的onResponse()方法和onFailure()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值