公司业务需求,需要调用API,里面涉及到http的访问请求,这里用到了http的一个访问的框架,自己写的工具类如下:
package com.xxxx.util;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* 利用okhttp进行get和post的访问
*
* @author cp
*
*/
public class OKHttpUtil {
/**
* 发起get请求
*
* @param url
* @return
*/
public static String httpGet(String url) {
String result = null;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
try {
Response response = client.newCall(request).execute();
result = response.body().string();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 发送httppost请求
*
* @param url
* @param data 提交的参数为key=value&key1=value1的形式
* @return
*/
public static String httpPost(String url, String data) {
String result = null;
OkHttpClient httpClient = new OkHttpClient();
RequestBody requestBody = RequestBody.create(MediaType.parse("text/html;charset=utf-8"), data);
Request request = new Request.Builder().url(url).post(requestBody).build();
try {
Response response = httpClient.newCall(request).execute();
result = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
okhttp的官网:http://square.github.io/okhttp/
时至今日,当我重拾Android的时候再回头看之前的代码,发现还是有问题的,当时还是太年轻^_^
网络请求通常是属于耗时操作,上述封装例子实际上方法内部没有开启线程,这样有可能导致调用上述方法的时候主线程会被阻塞,所以需要开启一个子线程,但是开启子线程之后,主线程如何得到返回的结果呢?
这里只要使用java的回调机制就可以了:
新代码如下:
使用HtppURLConnection 需要自己定义一个回调接口:
package com.example.chenpeng.utils;
public interface HttpCallBackListener {
void onFinish(String response);
void onError(Exception e);
}
这样封装后的工具类应该如下:
package com.example.chenpeng.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class HttpUtil {
/**
* 使用HttpURLConnection
* @param address
* @param listener
*/
public static void 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.setReadTimeout(8000);
connection.setConnectTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(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) {
listener.onFinish(response.toString());
}
} catch (IOException e) {
if (listener != null) {
listener.onError(e);
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
/**
* 使用okhttp请求
* @param address
* @param callback
*/
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);
}
}
在okhttp中已经为我们定好了回调接口就不需要自己定义了。
gradle引入okhttp的包:
如何使用呢?
代码如下:
public static void main(String[] args) {
// HttpURLConnection
HttpUtil.sendHttpRequest("xxxx", new HttpCallBackListener() {
@Override
public void onFinish(String response) {
// 这里执行返回逻辑
}
@Override
public void onError(Exception e) {
// 错误处理
}
});
// OKHttp
HttpUtil.sendOkHttpRequest("xxx", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 失败处理
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 成功处理
}
});
}