This article Outlines why YOU chose OKHTTP as your project network library, and how you can repackage it into a Module for easy use

Note: See article for advanced version of MyOkHttp:

Juejin. Cn/post / 684490…

Android Architecture series

This series of articles will update you on some of the best architecture and tips for Android project development

How to write an Intent series 3 Android architecture series 3 Android architecture series 4 Android architecture series 5 Encapsulate your own OkHTTP series Android Architecture Series – Practical application of MVP architecture

1 Network library selection and why abandoned Retrofit

The network library of choice for the original project was the most popular retrofit+ OKHTTP +gson. There are also records in the following version.

Version of the record

But!!! Later, we ran into the problem that the API provided by the server could not follow the Restful API format, and the formats of different modules could not be consistent because they were developed separately from the service. As a result, the implementation of the API interface layer is very farfetched. Ultimately, the API layer is not written to focus on the business, which is counterproductive. (At least the current server is not suitable for retrofit)

The decision was made to ditch Retrofit and use its own repackaged okHTTP.

2 Encapsulation uses OKHTTP

The encapsulation process refers to:

It’s time to learn more about OkHttp

Kaiqiang Zhao’s open source project OkHttpPlus

2.1 How to Use it

Let’s start with how the encapsulated OKHTTP +gson works. (Encapsulates POST request,GET request, upload file, download file, cancel request and Gson conversion and other functions)

2.1.1 POST request

Map<String, String> params = new HashMap<String, String>();
params.put("name"."tsy");

MyOkHttp.get().post(this."http://192.168.3.1/test_okhttp.php", params, new JsonResponseHandler() {
    @Override
    public void onSuccess(int statusCode, JSONObject response) {
        LogUtils.v(TAG, statusCode + "" + response);
    }

    @Override
    public void onFailure(int statusCode, String error_msg) {
        LogUtils.v(TAG, statusCode + ""+ error_msg); }});Copy the code

2.1.2 GET request

Map<String, String> params = new HashMap<String, String>();
params.put("name"."tsy");

MyOkHttp.get().get(this."http://192.168.3.1/test_okhttp.php", params, new RawResponseHandler() {
    @Override
    public void onSuccess(int statusCode, String response) {
        LogUtils.v(TAG, statusCode + "" + response);
    }

    @Override
    public void onFailure(int statusCode, String error_msg) {
        LogUtils.v(TAG, statusCode + ""+ error_msg); }});Copy the code

2.1.3 Uploading files

Map<String, String> params = new HashMap<String, String>();
params.put("name"."tsy");

Map<String, File> files = new HashMap<String, File>();
File file = new File(Environment.getExternalStorageDirectory() + "/com.ci123.service.splashandroid/splash/1.png");
files.put("avatar", file);

MyOkHttp.get().upload(this."http://192.168.3.1/test_post.php", params, files, new GsonResponseHandler<BB>() {
    @Override
    public void onFailure(int statusCode, String error_msg) {
        LogUtils.v(TAG, statusCode + "" + error_msg);
    }

    @Override
    public void onSuccess(int statusCode, BB response) {
        LogUtils.v(TAG, statusCode + "" + response.ret);
    }

    @Override
    public void onProgress(long currentBytes, long totalBytes) {
        LogUtils.v(TAG, currentBytes + "/"+ totalBytes); }});Copy the code

2.1.4 Downloading files

MyOkHttp.get().download(this."http://192.168.3.1/output_tmp.jpg",
        Environment.getExternalStorageDirectory() + "/com.tsy.splashandroid/"."1.jpg".new DownloadResponseHandler() {
    @Override
    public void onFinish(File download_file) {
        LogUtils.v(TAG, "onFinish:" + download_file.getPath());
    }

    @Override
    public void onProgress(long currentBytes, long totalBytes) {
        LogUtils.v(TAG, currentBytes + "/" + totalBytes);
    }

    @Override
    public void onFailure(String error_msg) { LogUtils.v(TAG, error_msg); }});Copy the code

2.1.5 request (suggestion on BaseActivity, BaseFragment onDestroy)

MyOkHttp.get().cancel(this);Copy the code

2.1.6 Return format

Post, GET and Upload interfaces can choose to return Json or Gson

  1. Normal JSON callbacks inherit from JsonResponseHandler, as in the POST request example

  2. The Gson callback inherits the GsonResponseHandler and sets the generic T, as in the example of the Upload request

  3. Raw Raw data callbacks inherit from RawResponseHandler, such as the GET request example

2.2 Source Code Parsing

The source code is integrated in BaseAndroidProject as the network module, which is encapsulated by module. Other projects can be taken directly from Module and used in the project.

Github address of BaseAndroidProject: github.com/tsy12321/Ba…

The source API entry is in the MyOkhttp file. The implementation of POST and GET requests is simple. Here I mainly explain how to encapsulate Gson Response and upload and download progress monitoring.

2.2.1 Gson Returns encapsulation

Gson was finally packaged into the following form of use:

MyOkHttp.get().post(this."http://192.168.3.1/test_okhttp.php", params, new GsonResponseHandler<BB>() {

    @Override
    public void onFailure(int statusCode, String error_msg) {
        LogUtils.v(TAG, statusCode + "" + error_msg);
    }

    @Override
    public void onSuccess(int statusCode, BB response) {
        LogUtils.v(TAG, statusCode + ""+ response.ret); }});Copy the code

GsonResponse differs from a normal JSON return in that the GsonResponseHandler constructor uses reflection to dynamically retrieve its own generic Type, and then saves that generic Type into a Type that Gson can use. This allows the Type to be converted to Gson when the result is called back.

public abstract class GsonResponseHandler<T> implements IResponseHandler {

    Type mType;

    public GsonResponseHandler(a) {
        Type myclass = getClass().getGenericSuperclass();    // reflection gets a generic class
        if (myclass instanceof Class) {
            throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameter = (ParameterizedType) myclass;      // Get all generics
        mType = $Gson$Types.canonicalize(parameter.getActualTypeArguments()[0]);  // Change the generic type to type
    }

    public final Type getType(a) {
        return mType;
    }

    public abstract void onSuccess(int statusCode, T response);

    @Override
    public void onProgress(long currentBytes, long totalBytes) {}}Copy the code

After okHTTP gets the response, it determines that responseHandler is GSON and converts the result to GSON format.

if(mResponseHandler instanceof JsonResponseHandler) {
    ...
} else if(mResponseHandler instanceof GsonResponseHandler) {
    mHandler.post(new Runnable() {
        @Override
        public void run(a) {
            try {
                Gson gson = new Gson();
                ((GsonResponseHandler)mResponseHandler).onSuccess(response.code(),
                        gson.fromJson(response_body, ((GsonResponseHandler)mResponseHandler).getType()));
            } catch (Exception e) {
                LogUtils.e("onResponse fail parse gson, body=" + response_body, e);
                mResponseHandler.onFailure(response.code(), "fail parse gson, body="+ response_body); }}}); }Copy the code

2.2.2 Monitoring progress of upload and download

This part refers to zhao Kaiqiang’s open source project OkHttpPlus, which is quite clear. The idea is to use OKio to override requestBody and responseBody, respectively, and set progress listening returns in the body. Just so so. Detailed principle can jump directly to the blog to learn ah, in this will not rebuild the wheel.

3 the end

In the end, OKHTTP was packaged as a module in which Gson and OKHTTP were introduced, so I didn’t export it as a JAR package. The future network base library will use this module!

The directory structure

More articles follow my public account

My official account