Android中搭建自己的项目网络框架
程序员文章站
2022-03-16 17:32:27
Android发展至今,先后出现了许多流行的网络框架,比如Xutils、OkHttp、Volley、Retrofit等框架,但是作为开发者,我们也应有自己的搭建网络框架的能里,以自...
Android发展至今,先后出现了许多流行的网络框架,比如Xutils、OkHttp、Volley、Retrofit等框架,但是作为开发者,我们也应有自己的搭建网络框架的能里,以自己的项目“量体裁衣”,另一方面,不是每一个网络框架都是没有缺点的比如
Xutils 网络请求框架的弊端:
1、请求方式、地址、参数都拆开了,应该封装到一个对象里面 2、请求之前应该判断网络 3、每次请求都new了一个RequestCallBack对象 4、请求得到的响应不知道是那次请求发出的 5、json的解析封装是耗时的操作不应该放到主线程 6、gson解析用流比字符串效率高很多 7、httpUtils基于HttpClient , HttpUrlConnection 扩展性很差,如果项目要用OkHttp之类的 NoHttp 8、错误的处理不应该让子类来处理 9、请求的响应应该分为三种:成功、其他的情况、错误现在我们开始搭建网络框架,下面是我们网络搭建的时序图:
添加依赖 okhttp、Gson
implementation ‘com.squareup.okhttp3:okhttp:3.10.0’ compile
compile ‘com.google.code.gson:gson:2.8.2’
添加权限:
/** * Created by MG_ZXC on 2018/3/22. * 封装:请求方式, 请求地址, 请求参数 */ public abstract class BaseRequest { public enum HttpMethod{ GET,POST; } public abstract HttpMethod getMethod(); public abstract String getUrl(); public abstract Map getParams(); }
BaseResponse类封装响应:
/** * Created by MG_ZXC on 2018/3/22. * 响应json数据的封装 */ public abstract class BaseResponse { //响应码 public int code; public T data; public boolean success() { return code >= 200 && code < 300; } }
声明接口 Callback结果回调:
/** * Created by MG_ZXC on 2018/3/22. * 请求结果回调 * 为了回调的时候告知当前的响应是哪次请求发出的,响应的方法把请求的BaseRequest传入 */ public interface Callback { void onError(BaseRequest request, Exception e); void onOther(BaseRequest request, Res response); void onSuccess(BaseRequest request, Res response); }
通过NetUtil发送网络请求:
public class NetUtil { private static ConnectivityManager connectivityManager; public static void init(Context context) { connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); } private static boolean checkNet() { NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null && activeNetworkInfo.isAvailable(); } /** * 通过NetUtil发送网络请求 * * @param request 请求的参数 * @param responseClass 相应的自字节码 * @param callback 请求的回调结果 * @param */ public static void sendRequest(BaseRequest request, Class responseClass, Callback callback) { //请求之前检查网络 if (checkNet()) { new NetTask().execute(new NetBean(request, responseClass, callback)); } else { callback.onError(request, new IllegalStateException("请检查网络")); } } //需要的对象:BaseRequest, Callback private static class NetTask extends AsyncTask { @Override protected NetBean doInBackground(NetBean[] params) { NetBean netBean = params[0]; try { Reader readerResponse = HttpWrapper.getInstance().getReaderResponse(netBean.request); BaseResponse response = new Gson().fromJson(readerResponse, netBean.responseClass); netBean.response = response; } catch (IOException e) { e.printStackTrace(); netBean.exception = e; } catch (JsonParseException e) { e.printStackTrace(); netBean.exception = e; } catch (Exception e) { e.printStackTrace(); netBean.exception = e; } return netBean; } @Override protected void onPostExecute(NetBean netBean) { //出现了异常 if (netBean.exception != null) { netBean.callback.onError(netBean.request, netBean.exception); } else { if (netBean.response.success()) { netBean.callback.onSuccess(netBean.request, netBean.response); } else { netBean.callback.onOther(netBean.request, netBean.response); } } } } private static class NetBean { public NetBean(BaseRequest request, Class responseClass, Callback callback) { this.request = request; this.callback = callback; this.responseClass = responseClass; } BaseRequest request; Callback callback; Class responseClass; //json解析封装的结果对象BaseResponse response BaseResponse response; Exception exception; } }
声明 HttpWrapper 对Http封装 :
/** * Created by MG_ZXC on 2018/3/22. * Http的封装,真正执行网络请求: OkHttp封装 */ public class HttpWrapper { private volatile static HttpWrapper singleton; private final OkHttpClient okHttpClient; private HttpWrapper() { okHttpClient = new OkHttpClient(); } public static HttpWrapper getInstance() { if (singleton == null) { synchronized (HttpWrapper.class) { if (singleton == null) { singleton = new HttpWrapper(); } } } return singleton; } //执行请求 get请求 :请求参数urlusername=zxc&password=123 //post 在请求体 public Reader getReaderResponse(BaseRequest request) throws IOException { return getResponseBody(request).charStream(); } public String getStringResponse(BaseRequest request) throws IOException { return getResponseBody(request).string(); } public byte[] getBytesResponse(BaseRequest request) throws IOException { return getResponseBody(request).bytes(); } public InputStream getInputStreamResponse(BaseRequest request) throws IOException { return getResponseBody(request).byteStream(); } private ResponseBody getResponseBody(BaseRequest request) throws IOException { Request.Builder builder = new Request.Builder(); if (request.getMethod() == BaseRequest.HttpMethod.GET) { StringBuilder stringBuilder = new StringBuilder(request.getUrl()); Map params = request.getParams(); if (params != null && params.size() > 0) { stringBuilder.append(""); Set keySet = params.keySet(); for (String key : keySet) { stringBuilder.append(key).append("=").append(URLEncoder.encode(params.get(key), "UTF-8")).append("&"); } stringBuilder.deleteCharAt(stringBuilder.length() - 1); } builder.url(stringBuilder.toString()).get(); } else if (request.getMethod() == BaseRequest.HttpMethod.POST) { //添加请求参数到请求体 FormBody.Builder formBody = new FormBody.Builder(); Map params = request.getParams(); if (params != null && params.size() > 0) { Set keySet = params.keySet(); for (String key : keySet) { formBody.addEncoded(key, params.get(key)); } } builder.url(request.getUrl()).post(formBody.build()); } ResponseBody body = okHttpClient.newCall(builder.build()).execute().body(); return body; } }
使用方式:
1,在 Application 中初始化 :
NetUtil.init(getApplicationContext());
2,使用
NetUtil.sendRequest(new TestRequest(), TestResponse.class, new Callback() { @Override public void onError(BaseRequest request, Exception e) { Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onOther(BaseRequest request, TestResponse response) { Toast.makeText(mContext, "其他错误", Toast.LENGTH_SHORT).show(); } @Override public void onSuccess(BaseRequest request, TestResponse response) { TestData data = response.data; content.setText(data.toString()); showSuccesStateView(); } });
public class TestData { /** * name : sz * score : 100 * sex : true */ private String name; private int score; private boolean sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public boolean isSex() { return sex; } public void setSex(boolean sex) { this.sex = sex; } @Override public String toString() { return "TestData{" + "name='" + name + '\'' + ", score=" + score + ", sex=" + sex + '}'; } }
public class TestResponse extends BaseResponse { }
public class TestRequest implements BaseRequest { @Override public HttpMethod getMethod() { return HttpMethod.POST; } @Override public String getUrl() { return Constant.format("TestServlet"); } @Override public Map getParams() { HashMap map = new HashMap<>(); map.put("username", "itcast"); map.put("password", "123&heima"); return map; } }
以上是网络框架的基本用法。实际上在开发中还可以优化形式出现比如(在基类中进行除数据请求成功的页面设置,在子类中进行,发送数据请求和处理数据请求正确的情况的):
在基类BaseFragment:
private OnSuccessCallback mOnSuccessCallback; //由父类发出请求在通知子类,错误,空数据由父类处理 public void sendRequest(BaseRequest request, Class responseClass, OnSuccessCallback onSuccessCallback) { mOnSuccessCallback = onSuccessCallback; NetUtil.sendRequest(request, responseClass, this); } @Override public void onError(BaseRequest request, Exception e) { //在基类中统一进行错误处理,比如错误页面的展示 } @Override public void onOther(BaseRequest request, BaseResponse response) { Toast.makeText(mContext, "其他错误", Toast.LENGTH_SHORT).show(); } //请求通知子类 @Override public void onSuccess(BaseRequest request, BaseResponse response) { if (response == null || response.data == null) { // 数据为空的情况 } else { //展示成功页面由子类处理 mOnSuccessCallback.onSuccess(request, response); } }
声明数据请求成功的情况的接口
public interface OnSuccessCallback { public void onSuccess(BaseRequest request, Res response); }
在子类中进行处理成功数据请求情况:
//调用父类sendRequest sendRequest(new TestRequest(), TestResponse.class, new OnSuccessCallback() { @Override public void onSuccess(BaseRequest request, TestResponse response) { //获取请求数据 }
推荐阅读
-
【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 完善
-
asp.net mvc 简单项目框架的搭建(二)—— Spring.Net在Mvc中的简单应用
-
【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构
-
【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.1 创建
-
Android中搭建自己的项目网络框架
-
搭建自己的 Android MVP 快速开发框架
-
【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构
-
【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构
-
asp.net mvc 简单项目框架的搭建(二)—— Spring.Net在Mvc中的简单应用
-
【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 完善