白羽
2018-11-15
来源 :网络
阅读 1282
评论 0
摘要:本文将带你了解Android应用开发Android中搭建自己的项目网络框架,希望本文对大家学Android有所帮助。
本文将带你了解Android应用开发Android中搭建自己的项目网络框架,希望本文对大家学Android有所帮助。
<
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’
添加权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
/** * 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();}</string,>
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; }}</t>
声明接口 Callback结果回调:
?1234567891011/** * Created by MG_ZXC on 2018/3/22. * 请求结果回调 * 为了回调的时候告知当前的响应是哪次请求发出的,响应的方法把请求的BaseRequest传入 */ public interface Callback <res baseresponse="" extends=""> { void onError(BaseRequest request, Exception e); void onOther(BaseRequest request, Res response); void onSuccess(BaseRequest request, Res response);}</res>
通过NetUtil发送网络请求:
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384public 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 baseresponse="" extends=""> 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, 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; }}</netbean,></res></res></res>
声明 HttpWrapper 对Http封装 :
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172/** * 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<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; }}</string></string,></string></string,>
使用方式:
1,在 Application 中初始化 :
?1NetUtil.init(getApplicationContext());
2,使用
?12345678910111213141516171819202122NetUtil.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(); } });</testresponse>
?1234567891011121314151617181920212223242526272829303132333435363738394041424344public 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> {}</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; }}</string,></string,>
以上是网络框架的基本用法。实际上在开发中还可以优化形式出现比如(在基类中进行除数据请求成功的页面设置,在子类中进行,发送数据请求和处理数据请求正确的情况的):
在基类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 baseresponse="" extends=""> { public void onSuccess(BaseRequest request, Res response);}</res>
在子类中进行处理成功数据请求情况:
//调用父类sendRequestsendRequest(new TestRequest(), TestResponse.class, new OnSuccessCallback<testresponse>() { @Override public void onSuccess(BaseRequest request, TestResponse response) { //获取请求数据 }</testresponse>
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!
喜欢 | 0
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号