联网请求数据一般都会使用okhttp,比retrofit相对简单。关于底层和原理就不再分析了,这里分享一下简单的封装,可以直接拿到项目中使用。
1.提取 MyNetClient,封装网络对象初始化。
package com.freevoip.airtime.net;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import com.freevoip.airtime.MyApp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class NetClient {
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static NetClient netClient;
private Handler handler;
private NetClient() {
client = getClient();
//使用传入一个 Looper的构造 把主线程的looper传进来 确保handler处理消息是在主线程中处理
handler = new Handler(Looper.getMainLooper());
}
public static NetClient getInstance() {
if (netClient == null) {
netClient = new NetClient();
}
return netClient;
}
private final OkHttpClient client;
private OkHttpClient getClient() {
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(5000, TimeUnit.MILLISECONDS)
.connectTimeout(5000, TimeUnit.MILLISECONDS)
.build();
return client;
}
public void doGet(String url, Map<String, Object> params, final MyCallBack callback) {
ArrayList tmpArray = new ArrayList<String>();
for (Map.Entry<String, Object> entry : params.entrySet()) {
tmpArray.add(entry.getKey());
}
for (int i = 0; i < tmpArray.size(); i++) {
String key = tmpArray.get(i).toString();
if (i == 0) {
url += "?" + key + "=" + params.get(key);
} else {
url += "&" + key + "=" + params.get(key);
}
}
Request request = new Request.Builder().url(url).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
//在主线程中执行回调方法
Toast.makeText(MyApp.getInstance(), "网络连接异常", Toast.LENGTH_SHORT).show();
callback.onFailure(-1);
}
});
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.code() == 200) {
final String json = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
callback.onResponse(json);
}
});
}else {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyApp.getInstance(), "网络连接异常", Toast.LENGTH_SHORT).show();
callback.onFailure(response.code());
}
});
}
}
});
}
public void doPost(String url, Map<String, Object> params, final MyCallBack callback) {
// http://blog.csdn.net/lmj623565791/article/details/47911083
FormBody.Builder bodyBuilder = new FormBody.Builder();
ArrayList tmpArray = new ArrayList<String>();
for (Map.Entry<String, Object> entry : params.entrySet()) {
tmpArray.add(entry.getKey());
}
for (int i = 0; i < tmpArray.size(); i++) {
String key = tmpArray.get(i).toString();
bodyBuilder.add(key, params.get(key).toString());
}
FormBody body = bodyBuilder.build();
Request request = new Request.Builder().url(url).post(body).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
//在主线程中执行回调方法
Toast.makeText(MyApp.getInstance(), "网络连接异常", Toast.LENGTH_SHORT).show();
callback.onFailure(-1);
}
});
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.code() == 200) {
final String json = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
callback.onResponse(json);
}
});
}else {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyApp.getInstance(), "网络连接异常", Toast.LENGTH_SHORT).show();
callback.onFailure(response.code());
}
});
}
}
});
}
}
当然也可以把request提取出来。
2.提取 MyApi,封装 API 请求参数。界面上可以不再关心网络参数
public class ApiUrls {
public static final String HOST="http://www.baidu.com.cn";
public static final String SENDCODE=HOST+"...接口内容";
}
3.提取 MyCallBack 接口,解耦网络回调。API 可以不再关心底层的网络类。
public interface MyCallBack {
void onFailure(int code);
void onResponse(String json);
}
封装了成功失败的方法。
从此,界面、API、Client 三层独立,互不影响。
在使用的时候只需要
//创建一个集合 传入接口所需参数
Map params = new LinkedHashMap();
params.put("tel", use);
params.put("passwd", pad);
//发起网络请求 传入请求url,接口参数,在回调中的成功失败方法处理逻辑
NetClient.getInstance().doPost(ApiUrls.LOGIN, params, new MyCallBack() {
@Override
public void onFailure(int code) {}
@Override
public void onResponse(String json) {
//这里这样写因为我的bean类继承了一个basebean 返回的所有json中都有成功失败的状态,根据basebean中的成功失败状态 设置数据传输,如果解析自己的数据可以忽略下面2行。
SKUserInfo userInfo = gson.fromJson(json, SKUserInfo.class);
if (userInfo.getSuccess()) {
}
});
这样简单的okhttp 三层网络封装就完成了,可以直接拿到项目中使用了。