一、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()方法。