Retrofit API declaration and inheritance

Retrofit 2.7 introduced Interface inheritance. This is great if you want to separate your API definition from the actual networking implementation. You can now define a “plain” interface as API contract, we’ll call this FooApi, and then have another (Retrofit specific) interface inherit from it and add all the Retrofit sugar.

There seems to be a small catch though to make this fully work. You need to make sure that your concrete Retrofit API does not get obfuscated. If it does, Retrofit will throw the following runtime exception: java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., @GET, @POST, etc.).

Let’s say we created this concrete API declaration and called it FooRetrofitApi. We’ve also wired up all Retrofit annotations so it is able to make requests to your API.

All that is left to do is to exclude your concrete API from obfuscation. Do so by adding the following to your ProGuard rules:

-keep class nl.ansuz.FooRetrofitApi { *; }

Bob’s your uncle!

P.S.

So why do the Retrofit annotations get stripped? I think that is because of the way the code is structured. If you follow clean code principles, you’ll end up referencing the FooApi throughout your project. The concrete FooRetrofitApi is only injected. As a result R8 might think that FooRetrofitApi can be more optimised than is actually the case.

Certificate pinning with OkHttp

Warning: Illegal string offset 'language' in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ansuz.nl/subdomains/blog/httpdocs/wp-content/plugins/igsyntax-hiliter/classes/frontend.php on line 513

A while back I wrote about “Using SSL right on Android“. If you are using OkHttp and/or Retrofit, this should be quite simple to implement. You can use the CertificatePinner class when building your OkHttpClient instance.

Example:

  1. CertificatePinner certificatePinner = new CertificatePinner.Builder()
  2.   .add("example.com", "your_pin")
  3.   .build();
  4.  
  5. new OkHttpClient.Builder()
  6.   .certificatePinner(certificatePinner)
  7.   .build();

More details about HTTPS and certificate pinning with OkHttp can be found on their Wiki, as well as a full example.