For Android developers, this library is one of the most important to have in the proverbial ‘tool belt’. It helps you create a meaningful and easy to understand ‘interface’ between your app and some web-service. But, have you ever wondered what’s behind the scenes?
I think the idea behind retrofit is brilliant. Kudos to the people who came up with it. This article will focus on the main technical solution that enables retrofit to work the way it does.
Before I dive deep into the technical details, I want to point out the elephant in the room.
You can’t instantiate an interface, generally speaking, in Java. There is no class implementing this interface, nor a generated class (like the ones you get from annotation processors). But in retrofit, you use an
instance of this
interface. So, how is this possible?
Proxies and invocation handlers.
The code above creates an instance out of thin air (dynamically, at runtime, by using Proxies). The invocation handler
(proxy, method, args1) -> lambda in this example) is the method called whenever the client calls any method on the proxy instance. This allows us to do whatever we want with the arguments passed and return whatever we want, depending on what method is called.
This is a very powerful tool. When you have a set of classes that do the same thing, and the only thing that is different can be expressed as a method call, using a proxy of an interface can be an option. Retrofit library does this. An HTTP request is created the same way no matter what the endpoint is, or what the parameters are. To have fine-grained control and leverage this pattern the library also uses annotations and reduces boilerplate.
You could use code generation with annotation processing to achieve a similar goal, but that would be a multi-step process that would slow down compilation. Although annotation processing is a very trendy approach used by many Android libraries, the compromise between slower runtime vs slower compilation IMHO is worth it. You might think that using Proxy would have an impact on the app performance, but the latency of the network request is far bigger than anything you could gain from using generated code.
I think it’s important for people to understand when it’s really useful to know about these niche features of a language.
Proxy , while not a very popular class in the Java SDK, when used properly, can be a very powerful solution.
My personal goal is to learn all I can about the technologies I work with and continuously improve my programming skills.