I didn’t expect Retrofit to be so popular, but I simply assumed it was because it came from the same source (Square) as OkHttp that it became so popular until I read the source code. Or maybe it’s because it supports RxJava that it’s just adding fuel to the fire.

When I looked at Retrofit’s source code later, I understood why it got so much attention, because it had all the advantages and was decoupled. Any particular need you can foresee can be easily extended.

Days without HTTP frameworks

Let’s take a look at how we did requests before the HTTP framework.

retrofit00.png

First, build request parameters because you can’t request HTTP in the main thread, so you have to have an Executer or thread enqueue, which runs your request through the server and gets the data back to your upper layer. It’s basically the four steps above, and in the days when there was no framework, to do a request, it was a hell of a lot of pain, you had to manage the thread switch yourself, you had to parse the data, you had to parse the data into objects, you had to switch back to the main thread, you had to call back to the top.

The gap lasted a long time. From 10 to 12, I got tired of writing repetitive code, so I had to figure out a way to encapsulate those changes, and just encapsulate them. Fortunately, the official AsyncTask, although there are many pits, but if you maintain a queue, there will be no problem. Even better, the data format has changed from XML to JSON. Gson freed his hands and never had to parse dom again.

Early HTTP frameworks

Over time, a number of real HTTP frameworks have emerged. Stay also draws lessons from many articles and encapsulates a framework suitable for its own business needs.

One of the things about frameworks in this era is that they are desperate to support all genres. For example, Volley supports returning bitmaps directly. XUtils is not only large and complete, but also to support multithreading download. In an age of scarcity, they have their reasons for being there. But if we still use Volley for image request, we still use xUtils or Afinal for each module. That doesn’t make any sense. Art has specialized, a hundred schools of thought contend period, shouldn’t choose the best one? (Stay has never really used the combination framework of xUtils and Afinal. Subconsciously, he told me that they are toxic. Once something goes wrong or needs to be extended, the cost will be too big.)

Retrofit

Ok, so with the development of the HTTP framework behind us, let’s just talk about Retrofit.

This article uses retrofit’s latest version 2.0.1 as an example. You can also go to Github and find a ‘parent-2.0.1’ tag. At present the code changes relatively big. 2.0.1 already uses OKHttp3, while 2.0.0-beta2 in my project is still okHttp2.5.

One of retroFIT’s greatest features is decoupling, which requires a large number of design patterns, which can be difficult to understand if you don’t understand any design patterns at all.

First, take a look at a simplified flow chart drawn by Stay (if there are any mistakes, please correct them), so the class diagram will not be drawn.

retrofit01.png

Stay marks places where the design pattern is clear.

Appearance mode, dynamic proxy mode, Policy mode, observer mode. Of course there are Builder mode, factory etc. I didn’t label these simple ones.

Let’s outline the process:

Build a proxy for a Service Interface using Retrofit

Retrofit03.png When you call a request method in the Service Interface, it is intercepted by the proxy.

Retrofit02.png parses invoke’s method through ServiceMethod, parsing annotations, passing parameters, and encapsulating them into the familiar Request. We then have the previously configured factory generate a specific CallAdapter, ResponseConverter, from the specific return value type, which we’ll explain later. New an OkHttpCall. This OkHttpCall is a wrapper for OkHttp and is used to connect to OkHttp. All OkHttp parameters can be seen in this class. It is also possible to extend a new Call, such as HttpUrlConnectionCall. But it’s a little bit coupled. Look at the label below:

The retroFIT031.png red box explicitly indicates the OkHttpCall, rather than the factory generating the Call. So if you don’t want to change the source code and recompile it, then you have to use OkHttp. But it doesn’t matter. The generated CallAdapter has four factories, one for each platform, RxJava, Java8, Guava and a Retrofit default. This CallAdapter is not easy to explain in Chinese. Simply put, this is a strategy for converting Call to T. Because the request is a time consuming operation, you need a CallAdapter to manage the thread. How to manage, read on. Such as RxJava according to call a method return values, such as the Response < ‘T > | Result <‘ T > | observables < ‘T >, generate different CallAdapter. This encapsulates RxJava’s callback method. For example, response is decomposed into success and error. In Step 5, we said that The CallAdapter also manages threads. We know, for example, that RxJava has the greatest advantage of specifying the thread on which the method is executed. As shown in figure

PNG we subscribeOn the child thread and observeOn the main thread. So how does it do that. Let’s look at the source code.

PNG retrofit05.png is subscribeOn when the Call is adapted, so it is switched to the child thread. In Adapt Call, Call execute() is called, execute() is synchronous, and enQueue () is asynchronous. Because RxJava has already switched threads, the synchronous method execute() is used here.

The next specific request for retrofit06.png, which is OkHttp, is to wait for the return value. In Step 4, we said that OkHttpCall is a wrapper class for OkHttp, so converting OkHttp’s response to T is also done in OkHttpCall. Of course, it’s not OkHttpCall’s job to parse the conversion, because it doesn’t know what the data format is. So it just wraps Response as response under RetroFIT. Converter->ResponseConverter, which is obviously a data Converter. It converts response to the specific T that we want. Retrofit offers many Converter Factories. Gson, Jackson, XML, Protobuff, etc. Deploy whatever factories you need. Declare generic concrete types on Service methods. Finally, a callback is made to the upper layer by the declared observeOn thread. So the upper echelon gets the final result. How to deal with the results is a matter for the top. Let’s review the flow chart drawn by Stay:

retrofit01.png

This is really a long journey. Stay is also a process of debug that is combed out by step by step debugging. Of course, there are a lot of clever ways of decoupling that I won’t go over here. You can look at the source code analysis, when it is a classic example of design patterns.

I think you know retrofit by now. When you introduce Retrofit to someone else, don’t just tell them how new and clever the annotations are. There are many annotated frameworks, such as j2ee. So annotation is not much of a skill. The best part is the decoupling method, which can’t be designed without years of practical architecture experience.

I am an old programmer who has been engaged in the backend for more than ten years. Now I am a lecturer after resignation. Recently, I spent a month to sort out a JAVA dry product most suitable for learning in 2019 (including high availability, high concurrency, high performance and distribution, Jvm performance tuning, Spring source code, MyBatis, Netty, Redis, Kafka, Mysql, Zookeeper, Tomcat, Docker, Dubbo, Nginx multiple knowledge such as the architecture of the data) is engaged in the backend, friends can learn about the secret here is a programmer, For those of you who are still struggling to become an architect, hop in.

QQ group: 668041364