An improved okHttp wrapper library for Android

Please indicate the source for reprinting:
http://blog.csdn.net/lmj623565791/article/details/49734867 ;
This article comes from: [Zhang Hongyang's blog]

I. Overview

I wrote a complete analysis of Android OkHttp before. It’s time to learn about OkHttp . In fact, it is mainly used as a popular article for okhttp. Of course, it also simply encapsulates tool classes. I didn’t expect that many people pay attention and use it. Because of this enthusiasm, The methods in this tool class have also increased dramatically, and various overloaded methods have made it extremely inconvenient to use, and I am ashamed.

Therefore, this weekend, I took some time to re-disassemble and write the tool class, and by the way, improve the functions and improve the convenience and scalability of its use as much as possible.

The improvement of the title also refers to the improvement of my previous code.

If you don't know about okhttp, you can fully parse through Android OkHttp. It's time to learn about OkHttp .

ok, then at present, the package library records support:

  • General get request
  • General post request
  • Http-based file upload
  • document dowload
  • Upload and download progress callback
  • load image
  • Support request callback, directly return objects and object collections
  • Support session retention
  • Support self-signed website https access, just provide the method to set the certificate
  • Support to cancel a request

Source address: https://github.com/hongyangAndroid/okhttp-utils


Introduce:

  • Android Studio

    Before use, for Android Studio users, you can choose to add:

    <code class="hljs scss has-numbering"></code><pre name="code" class="java">compile project(':okhttputils')


     

    or

    compile 'com.zhy:okhttputils:2.0.0'

  • Eclipse

    Copy the source code yourself.

2. Basic usage

The current basic usage format is:

OkHttpUtils
    .get()
    .url(url)
    .addParams("username", "hyman")
    .addParams("password", "123")
    .build()
    .execute(callback);


By chaining, you can add various parameters according to your needs, and finally call execute(callback) to execute. The incoming callback means asynchronous. A simple execute() represents a synchronous method call.

It can be seen that the previous bunch of get overloaded methods have been cancelled, and the parameters can also be flexibly selected.

Here's a brief look at all the usages:

(1) GET request

String url = "http://www.csdn.net/";
OkHttpUtils
    .get()
    .url(url)
    .addParams("username", "hyman")
    .addParams("password", "123")
    .build()
    .execute(new StringCallback()
            {
                @Override
                public void onError(Request request, Exception e)
                {

                }

                @Override
                public void onResponse(String response)
                {

                }
            });


(2) POST request

 OkHttpUtils
    .post()
    .url(url)
    .addParams("username", "hyman")
    .addParams("password", "123")
    .build()
    .execute(callback);


(3)Post String

OkHttpUtils
    .postString()
    .url(url)
    .content(new Gson().toJson(new User("zhy", "123")))
    .build()
    .execute(new MyStringCallback());   


Pass the string as the request body to the server, such as a json string.

(4)Post File

OkHttpUtils
    .postFile()
    .url(url)
    .file(file)
    .build()
    .execute(new MyStringCallback());


Pass the file as the request body to the server.

(5) POST-based file upload (similar to forms on the web)

OkHttpUtils.post()//
    .addFile("mFile", "messenger_01.png", file)//
    .addFile("mFile", "test1.txt", file2)//
    .url(url)
    .params(params)//
    .headers(headers)//
    .build()//
    .execute(new MyStringCallback());


(6) Download files

OkHttpUtils//
    .get()//
    .url(url)//
    .build()//
    .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "gson-2.2.1.jar")//
    {
        @Override
        public void inProgress(float progress)
        {
            mProgressBar.setProgress((int) (100 * progress));
        }

        @Override
        public void onError(Request request, Exception e)
        {
            Log.e(TAG, "onError :" + e.getMessage());
        }

        @Override
        public void onResponse(File file)
        {
            Log.e(TAG, "onResponse :" + file.getAbsolutePath());
        }
    });


(7) Display pictures

OkHttpUtils
    .get()//
    .url(url)//
    .build()//
    .execute(new BitmapCallback()
    {
        @Override
        public void onError(Request request, Exception e)
        {
            mTv.setText("onError:" + e.getMessage());
        }

        @Override
        public void onResponse(Bitmap bitmap)
        {
            mImageView.setImageBitmap(bitmap);
        }
    });


Ha, now it's much clearer.

3. Callback for upload and download

new Callback<?>()
{
    //...
    @Override
    public void inProgress(float progress)
    {
       //use progress: 0 ~ 1
    }
}


There is an inProgress method for the incoming callback, which needs to be overwritten directly to get the progress.

Fourth, for automatic resolution to entity classes

At present, the dependency of Gson is removed, and a custom Callback method is provided, allowing users to parse the returned data by themselves. Currently StringCallback, FileCallback, BitmapCallbackare provided for returning strings, downloading files, and loading pictures.

Of course if you wish to resolve to an object, you can:

public abstract class UserCallback extends Callback<User>
{
    //非UI线程,支持任何耗时操作
    @Override
    public User parseNetworkResponse(Response response) throws IOException
    {
        String string = response.body().string();
        User user = new Gson().fromJson(string, User.class);
        return user;
    }
}

You can use your favorite Json parsing library to complete it.

It is parsed as List<User>follows:

public abstract class ListUserCallback extends Callback<List<User>>
{
    @Override
    public List<User> parseNetworkResponse(Response response) throws IOException
    {
        String string = response.body().string();
        List<User> user = new Gson().fromJson(string, List.class);
        return user;
    }


}

Five, for https one-way authentication

Very simple, get the certificate of xxx.cert.

then call

OkHttpUtils.getInstance()
        .setCertificates(inputstream);

The recommended way to use, for example, my certificate is placed in the assets directory:

/**
 * Created by zhy on 15/8/25.
 */
public class MyApplication extends Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();

        try
        {    
        OkHttpUtils
         .getInstance()
         .setCertificates(getAssets().open("aaa.cer"),
 getAssets().open("server.cer"));
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

That's it. Don't forget to register Application.

Note: If the https website is a certificate issued by an authority, the above settings are not required. Self-signed certificates are required.

6. Configuration

(1) Global configuration

In Application, through:

OkHttpClient client = 
OkHttpUtils.getInstance().getOkHttpClient();

Then call the various set methods of the client.

E.g:

client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);

(2) Set a timeout for a single request

For example, when it comes to files, it is necessary to set the read and write waiting time a little more.

OkHttpUtils
    .get()//
    .url(url)//
    .tag(this)//
    .build()//
    .connTimeOut(20000)
    .readTimeOut(20000)
    .writeTimeOut(20000)
    .execute()

After calling build(), various timeOuts can be set immediately.

(3) Cancel a single request

<code class="language-java hljs  has-numbering"></code><pre name="code" class="java"> RequestCall call = OkHttpUtils.get().url(url).build();
 call.cancel();

 
  

(4) Cancel the request according to the tag

At present, the last parameter is added to the supported methods Object tag, and the cancellation is performed by OkHttpUtils.cancelTag(tag)execution.

For example: in an Activity, when the Activity is destroyed to cancel the request:

OkHttpUtils
    .get()//
    .url(url)//
    .tag(this)//
    .build()//

@Override
protected void onDestroy()
{
    super.onDestroy();
    //可以取消同一个tag的
    OkHttpUtils.cancelTag(this);//取消以Activity.this作为tag的请求
}

For example, all requests on the current Activity page use the Activity object as a tag, which can be canceled uniformly in onDestory.

Seven, talk about packaging

In fact, the entire encapsulation process is relatively simple. Here is a brief description. The process of a request for okhttp is roughly as follows:

//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
                .url("https://github.com/hongyangAndroid")
                .build();
//new call
Call call = mOkHttpClient.newCall(request); 
//请求加入调度
call.enqueue(new Callback()
{
    @Override
    public void onFailure(Request request, IOException e)
    {
    }

    @Override
    public void onResponse(final Response response) throws IOException
    {
            //String htmlStr =  response.body().string();
    }
});    

The main difference is actually the construction process of the request.

I abstract a class for Request:OkHttpRequest

public abstract class OkHttpRequest
{
    protected RequestBody requestBody;
    protected Request request;

    protected String url;
    protected String tag;
    protected Map<String, String> params;
    protected Map<String, String> headers;

    protected OkHttpRequest(String url, String tag,
                            Map<String, String> params, Map<String, String> headers)
    {
        this.url = url;
        this.tag = tag;
        this.params = params;
        this.headers = headers;
    }

    protected abstract Request buildRequest();
    protected abstract RequestBody buildRequestBody();

    protected void prepareInvoked(ResultCallback callback)
    {
        requestBody = buildRequestBody();
        requestBody = wrapRequestBody(requestBody, callback);
        request = buildRequest();
    }

    protected RequestBody wrapRequestBody(RequestBody requestBody, final ResultCallback callback)
    {
        return requestBody;
    }


    public void invokeAsyn(ResultCallback callback)
    {
        prepareInvoked(callback);
        mOkHttpClientManager.execute(request, callback);
    }


     // other common methods
 }   

For the construction of a request, I divide it into three steps: buildRequestBody, wrapRequestBody, in buildRequestthis order, when the above three methods are no problem, we will get the request and then execute it.

But for different requests, the construction process of requestBody and request is different, so you can see buildRequestBodythat buildRequestfor abstract methods, that is, different request classes, such as OkHttpGetRequest, OkHttpPostRequestetc., need to build their own requests.

As for the wrapRequestBodymethod, you can see that it is basically an empty implementation by default, mainly because not all request classes need to overwrite it. Only when uploading, you need to call back the progress and wrap the requestBody, so this method is similar to a hook. .

In fact, this process is somewhat similar to the template method pattern. If you are interested, you can take a look at a short introduction to the design pattern template method pattern to show a programmer's day .

For more detailed usage, you can check the readme on github and the demo. The demo currently includes:

For the two buttons for uploading files, you need to build your own server, and the other buttons can be tested directly.

Finally, due to my limited level and the rush of time~~I find problems, welcome to raise issues, and I will take the time to solve them. have a nice day ~

Source code click to download


Welcome to follow my Weibo:
http://weibo.com/u/3165018720


Group number: 514447580 , welcome to join the group

WeChat public account: hongyangAndroid
(welcome to pay attention, push blog information as soon as possible)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324064329&siteId=291194637