Introduction to the

OkOne is a network performance optimization framework based on the OKHTTP library, but unlike other frameworks that encapsulate okHTTP usage calls, it is optimized in a way that is non-intrusive to the developer in a different way.

Pain points

APP projects may contain multiple component modules, or rely on multiple tripartite libraries, or even develop AAR business modules for APP integration by different teams of departments. There may be network requests using the OKHTTP framework, instances of OkHttpClient created in different component modules and tripartite libraries, or developers creating OkHttpClient each time they request it instead of singleton caching. This is wasteful and results in inadequate control and optimization measures such as request queuing and connection pooling for OKHTTP.

To solve

The OkOne library enables non-intrusive convergence of OkHttpClient, which is distributed in different components, and unified management and reuse by OkOne. OkOne compares okHttpClient. Builder to okHttpClient. Builder, that is, okHttpClient. Builder with the same configuration will automatically reuse the same OkHttpClient instance.

integration

Integration is simple in three steps:

Minimum supported Gradle version is 6.5

  • 1. Add dependencies to build. Gradle in the project root directory
dependencies {

    classpath 'com. CDH. Okone: gradle: 0.1.0 from'

}

Copy the code
  • 2. Apply the plugin in build.gradle of app Module
apply plugin: 'plugin.cdh.okone'

Copy the code
  • Add dependencies to build. Gradle in the App Module
implementation 'com. CDH. Okone: okone: 0.1.2'

Copy the code

The connection has been completed and the operation will take effect automatically.

The effect

Now to see this in action, create three okHttpClient.Builder with different configurations in the demo:

// builder1

OkHttpClient.Builder builder1 = new OkHttpClient.Builder()

    .connectTimeout(10, TimeUnit.SECONDS)

    .addInterceptor(new HttpLoggingInterceptor())

    .eventListener(mEventListener);

    

// builder2

OkHttpClient.Builder builder2 = new OkHttpClient.Builder()

    .retryOnConnectionFailure(true)

    .minWebSocketMessageToCompress(2048)

    .eventListener(mEventListener);

    testRequestServer(builder2);



// builder3

OkHttpClient.Builder builder3 = new OkHttpClient.Builder()

    .connectTimeout(10, TimeUnit.SECONDS)

    .addInterceptor(new HttpLoggingInterceptor())

    .retryOnConnectionFailure(true)

    .minWebSocketMessageToCompress(2048)

    .eventListener(mEventListener);

Copy the code

Examples of reuse

Then build OkHttpClient with each of these three builders for the request:

    private void testRequestServer(OkHttpClient.Builder builder) {

        // Do not cache the client, build each time

        OkHttpClient client = builder.build();

        // Prints logs

        Log.d(TAG, "Create OkHttpClient:" + client);



        Request request = new Request.Builder()

                .url(api)

                .build();

        Call call = client.newCall(request);

        call.enqueue(new Callback() {

            @Override

            public void onFailure(@NotNull Call call, @NotNull IOException e) {}



            @Override

            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {}

        });

    }

Copy the code

You can see that an OkHttpClient is built each time to make the request.

Now call in the following order:

// Use builder1 twice first

testRequestServer(newBuilder1());

testRequestServer(newBuilder1());

// Change the builder2 request twice

testRequestServer(newBuilder2());

testRequestServer(newBuilder2());

// Change to builder3 twice

testRequestServer(newBuilder3());

testRequestServer(newBuilder3());

Copy the code

Then look at the print log:

You can see that OkOne successfully re-uses the OkHttpClient instance, and while each request builds to get the OkHttpClient, it doesn’t actually produce multiple instances. Builder1, Builder2, builder3 builds reuse their OkHttpClient. If OkOne is not integrated, six OkHttpClient instances will be generated.

Connection reuse

To see if the connection was successfully reused, add a log to EventListener to check:

private EventListener mEventListener = new EventListener() {

    // Add a Log print Log to each override method

    // The code is omitted for space

}

Copy the code

Set up a custom eventListener with okHttpClient.builder #eventListener.

Builder1, Builder1, Builder2, Builder2, Builder3, Builder3

  • Builder1 first requestYou can see that there is currently no reusable connection, and the request goes through DNS and handshake setup.

  • Builder1 second requestThis request has a multiplexed connection, eliminating DNS and handshake setup. If OkOne is not integrated, a full link-building process will also go through.

  • Builder2 first requestBuilder2 is configured differently from Builder1. Builder1’s OkHttpClient is not reused, so the full request process is followed.

  • Builder2 second requestThe request does not have to be DNS and handshake.

  • Builder3 first requestCreate an OkHttpClient with no multiplexing connection.

  • Builder3 second requestSuccessful reuse.

You can see that okHTTP’s connection pool is effectively utilized, avoiding the DNS re-routing and handshake connection establishment process on every request. If the OkOne library is not integrated, the full request process is followed each time.

More functions

Close the switch

Whether to enable or disable unified reuse and management of OkHttpClient must be set before creating OkHttpClient.

// trueEnabled,falseShut down. The defaulttrue.

OkOne.useGlobalClient = true;

Copy the code

Print log

Turn on or off the OkOne print log.

// truePrint,falseDon't print. The defaulttrue.

OkOne.setLogEnable(true);

Copy the code

Create a separate uncontrolled OkHttpClient instance

Create a separate OkHttpClient that is not managed and reused by OkOne.

OkHttpClient client = new OkHttpClient(builder); 

Copy the code

Making the address

Github.com/chidehang/O…