Android中网络框架的简单封装

hqulyc 2020-03-05

个人博客

http://www.milovetingting.cn

Android中网络框架的简单封装

前言

Android作为一款主要应用在移动终端的操作系统,访问网络是必不可少的功能。访问网络,最基本的接口有:HttpUrlConnection,HttpClient,而在后续的发展中,出现了VolleyOkHttpRetrofit等网络封装库。由于各种原因,在实际的项目开发中,我们可能会需要在项目的版本迭代中,切换网络框架。如果对于网络框架没有好的封装,那么当需要切换网络框架时,可能就会有大量的迁移工作要做。

封装网络框架

在架构设计中,面向接口抽象,是解耦的一个重要原则。本文将基于这一原则,实现一个简单的网络框架封装。

定义网络访问的接口

抽取出不同网络框架的共同方法,定义成接口方法。

public interface IHttpLoader {

    /**
     * GET方式请求
     *
     * @param url
     * @param params
     * @param callback
     */
    void get(String url, Map<String, Object> params, IHttpCallback callback);

    /**
     * POST方式请求
     *
     * @param url
     * @param params
     * @param callback
     */
    void post(String url, Map<String, Object> params, IHttpCallback callback);

}

定义网络访问的Callback

public interface IHttpCallback {

    /**
     * 成功时的回调
     *
     * @param result
     */
    void onSuccess(String result);

    /**
     * 失败时的回调
     *
     * @param msg
     */
    void onFailed(String msg);

}

定义具体的接口实现类

分别对具体的网络框架进行接口实现,这里以Volley和OkHttp为例

Volley的实现类

public class VolleyHttpLoader implements IHttpLoader {

    private static RequestQueue mRequestQueue;

    public VolleyHttpLoader(Context context) {
        mRequestQueue = Volley.newRequestQueue(context);
    }

    @Override
    public void get(String url, Map<String, Object> params, final IHttpCallback callback) {
        StringRequest request = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String s) {
                        callback.onSuccess(s);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                callback.onFailed(volleyError.toString());
            }
        });
        mRequestQueue.add(request);
    }

    @Override
    public void post(String url, Map<String, Object> params, final IHttpCallback callback) {
        StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String s) {
                        callback.onSuccess(s);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                callback.onFailed(volleyError.toString());
            }
        });
        mRequestQueue.add(request);
    }
}

OkHttp的实现类

public class OkHttpLoader implements IHttpLoader {

    private static OkHttpClient mOkHttpClient;

    public OkHttpLoader() {
        mOkHttpClient = new OkHttpClient();
    }


    @Override
    public void get(String url, Map<String, Object> params, final IHttpCallback callback) {
        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                callback.onFailed(e.toString());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    String result = response.body().string();
                    callback.onSuccess(result);
                } else {
                    callback.onFailed(response.message());
                }
            }
        });
    }

    @Override
    public void post(String url, Map<String, Object> params, final IHttpCallback callback) {
        RequestBody requestBody = appendBody(params);
        Request request = new Request.Builder().post(requestBody).url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                callback.onFailed(e.toString());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    String result = response.body().string();
                    callback.onSuccess(result);
                } else {
                    callback.onFailed(response.message());
                }
            }
        });
    }

    private RequestBody appendBody(Map<String, Object> params) {
        FormBody.Builder body = new FormBody.Builder();
        if (params == null || params.isEmpty()) {
            return body.build();
        }
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            body.add(entry.getKey(), entry.getValue().toString());
        }
        return body.build();
    }
}

定义Callback的实现

public abstract class HttpCallback<Result> implements IHttpCallback {

    @Override
    public void onSuccess(String result) {
        Gson gson = new Gson();
        Class<?> clazz = analysisClazzInfo(this);
        Result resultObj = (Result) gson.fromJson(result, clazz);
        onSuccess(resultObj);
    }

    /**
     * 成功时的回调
     *
     * @param result
     */
    public abstract void onSuccess(Result result);

    private Class<?> analysisClazzInfo(Object object) {
        Type genType = object.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        return (Class<?>) params[0];
    }
}

返回的数据Bean

public class Data {

    private int errorCode;
    private String errorMsg;
    private List<DataBean> data;

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {

        private int courseId;
        private int id;
        private String name;
        private int order;
        private int parentChapterId;
        private boolean userControlSetTop;
        private int visible;
        private List<?> children;

        public int getCourseId() {
            return courseId;
        }

        public void setCourseId(int courseId) {
            this.courseId = courseId;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getOrder() {
            return order;
        }

        public void setOrder(int order) {
            this.order = order;
        }

        public int getParentChapterId() {
            return parentChapterId;
        }

        public void setParentChapterId(int parentChapterId) {
            this.parentChapterId = parentChapterId;
        }

        public boolean isUserControlSetTop() {
            return userControlSetTop;
        }

        public void setUserControlSetTop(boolean userControlSetTop) {
            this.userControlSetTop = userControlSetTop;
        }

        public int getVisible() {
            return visible;
        }

        public void setVisible(int visible) {
            this.visible = visible;
        }

        public List<?> getChildren() {
            return children;
        }

        public void setChildren(List<?> children) {
            this.children = children;
        }

        @Override
        public String toString() {
            return "DataBean{" +
                    "courseId=" + courseId +
                    ", id=" + id +
                    ", name='" + name + '\'' +
                    ", order=" + order +
                    ", parentChapterId=" + parentChapterId +
                    ", userControlSetTop=" + userControlSetTop +
                    ", visible=" + visible +
                    ", children=" + children +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "Data{" +
                "errorCode=" + errorCode +
                ", errorMsg='" + errorMsg + '\'' +
                ", data=" + data +
                '}';
    }

}

定义统一管理类

public class HttpHelper implements IHttpLoader {

    private static IHttpLoader mHttpLoader;

    private HttpHelper() {

    }

    public static void init(IHttpLoader httpLoader) {
        mHttpLoader = httpLoader;
    }

    public static HttpHelper obtain() {
        return HttpHelperHolder.INSTANCE;
    }

    static class HttpHelperHolder {
        private static HttpHelper INSTANCE = new HttpHelper();
    }

    @Override
    public void get(String url, Map<String, Object> params, IHttpCallback callback) {
        mHttpLoader.get(url, params, callback);
    }

    @Override
    public void post(String url, Map<String, Object> params, IHttpCallback callback) {
        mHttpLoader.post(url, params, callback);
    }
}

在Application中初始化

定义一个继承自Application的类,在onCreate方法中初始化网络访问

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
//        HttpHelper.init(new OkHttpLoader());
        HttpHelper.init(new VolleyHttpLoader(this));
    }
}

后续如果需要切换网络框架,只需要在这里修改就可以了。

应用

public class MainActivity extends AppCompatActivity {

    private static final String URL_HTTP = "https://www.wanandroid.com/wxarticle/chapters/json";

    private ImageView mIv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTv = findViewById(R.id.tv);

        findViewById(R.id.btn_get).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HttpHelper.obtain().get(URL_HTTP, null, new HttpCallback<Data>() {
                    @Override
                    public void onFailed(final String msg) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mTv.setText(msg);
                            }
                        });
                    }

                    @Override
                    public void onSuccess(final Data data) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mTv.setText(data.toString());
                            }
                        });
                    }
                });
            }
        });

    }
}

结束

这里介绍的,其实只是一个封装的思路。基于这个思路,还可以封装常用的图片访问库等。可以自由拓展。

源码

源码地址:https://github.com/milovetingting/Samples/tree/master/Loader

相关推荐