频道栏目
首页 > 资讯 > Android > 正文

Android中搭建自己的项目网络框架

18-03-23        来源:[db:作者]  
收藏   我要投稿

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) {
      //获取请求数据
 }
相关TAG标签
上一篇:交换机与路由器的区别详细介绍
下一篇:圆的旋转 类的派生与继承
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站