Android中搭建自己的项目网络框架
2018-03-22 21:31
591 查看
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’
添加权限:
BaseResponse类封装响应:
声明接口 Callback结果回调:
通过NetUtil发送网络请求:
声明 HttpWrapper 对Http封装 :
使用方式:
1,在 Application 中初始化 :
2,使用
以上是网络框架的基本用法。实际上在开发中还可以优化形式出现比如(在基类中进行除数据请求成功的页面设置,在子类中进行,发送数据请求和处理数据请求正确的情况的):
在基类BaseFragment:
声明数据请求成功的情况的接口
在子类中进行处理成功数据请求情况:
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’
添加权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
/** * 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<String, String> getParams(); }
BaseResponse类封装响应:
/** * Created by MG_ZXC on 2018/3/22. * 响应json数据的封装 */ public abstract class BaseResponse <T> { //响应码 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 <Res extends BaseResponse> { 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 <Res> */ public static <Res extends BaseResponse> void sendRequest(BaseRequest request, Class<Res> 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<NetBean, Void, NetBean> { @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<? extends BaseResponse> responseClass, Callback callback) { this.request = request; this.callback = callback; this.responseClass = responseClass; } BaseRequest request; Callback callback; Class<? extends BaseResponse> 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请求 :请求参数url?username=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<String, String> params = request.getParams(); if (params != null && params.size() > 0) { stringBuilder.append("?"); Set<String> 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<String, String> params = request.getParams(); if (params != null && params.size() > 0) { Set<String> 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<TestResponse>() { @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<TestData> { }
public class TestRequest implements BaseRequest { @Override public HttpMethod getMethod() { return HttpMethod.POST; } @Override public String getUrl() { return Constant.format("TestServlet"); } @Override public Map<String, String> getParams() { HashMap<String, String> map = new HashMap<>(); map.put("username", "itcast"); map.put("password", "123&heima"); return map; } }
以上是网络框架的基本用法。实际上在开发中还可以优化形式出现比如(在基类中进行除数据请求成功的页面设置,在子类中进行,发送数据请求和处理数据请求正确的情况的):
在基类BaseFragment:
private OnSuccessCallback mOnSuccessCallback; //由父类发出请求在通知子类,错误,空数据由父类处理 public void sendRequest(BaseRequest request, Class<? extends BaseResponse> 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<Res extends BaseResponse> { public void onSuccess(BaseRequest request, Res response); }
在子类中进行处理成功数据请求情况:
//调用父类sendRequest sendRequest(new TestRequest(), TestResponse.class, new OnSuccessCallback<TestResponse>() { @Override public void onSuccess(BaseRequest request, TestResponse response) { //获取请求数据 }
相关文章推荐
- 搭建自己的框架之3:项目中引入Dagger2&Dagger.android
- android ui定义自己的dialog(项目框架搭建时就写好,之后事半功倍)
- 自己搭建Android项目框架必备的框架与第三方应用
- Android用Okhttp搭建自己的网络框架
- 从框架到完整项目搭建,实战项目《约个球》(5)-为我们自己的框架导入网络的开源框架
- android ui定义自己的dialog(项目框架搭建时就写好,之后事半功倍)
- android真实项目教程(一)——App应用框架搭建_by_CJJ
- Android项目框架搭建 (分析需求、整理资料)
- Android学习之——自己搭建Http框架(2)——框架扩展
- Android项目框架搭建 (分析需求、整理资料)
- android框架搭建——封装一个属于自己的网络工具类
- android 项目框架搭建
- 使用Retrofit搭建自己的网络请求框架
- 用.Net打造一个移动客户端(Android/IOS)的服务端框架NHM(三)——搭建Android开发环境,用Hibernate生成Android项目的Model层
- Android项目框架搭建
- 【Android】自己写的轻量级安卓网络框架——能够控制网络连接,支持缓存
- 1、Android项目框架搭建 (分析需求、整理资料)
- cocos2d for android 环境搭建并生成自己的项目
- android 项目中使用到的网络请求框架以及如何配置好接口URL
- 自己封装的android客户端http网络框架