Reputation: 426
When using the retrofit library, you create an interface that contains functions with all your endpoints but you never implement it anywhere. My question is where is this interface implemented? I have noticed the same pattern when creating a DAO when using android Room
Upvotes: 2
Views: 519
Reputation: 101
Room Database uses the Annotation Processor and Reflection simultaneously. It uses Annotation Processor to generate Java Code for classes annotated as @DAO
and @Database
and generates implementation class with _Impl
suffix.
It uses reflection to find the Database implementation class. When you call Room.databaseBuilder(context, AppDatabase.class, databaseName).build();
It will call like this with the value of suffix being _Impl
@NonNull
static <T, C> T getGeneratedImplementation(Class<C> klass, String suffix) {
final String fullPackage = klass.getPackage().getName();
String name = klass.getCanonicalName();
final String postPackageName = fullPackage.isEmpty()
? name
: (name.substring(fullPackage.length() + 1));
final String implName = postPackageName.replace('.', '_') + suffix;
//noinspection TryWithIdenticalCatches
try {
@SuppressWarnings("unchecked")
final Class<T> aClass = (Class<T>) Class.forName(
fullPackage.isEmpty() ? implName : fullPackage + "." + implName);
return aClass.newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException("cannot find implementation for "
+ klass.getCanonicalName() + ". " + implName + " does not exist");
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot access the constructor"
+ klass.getCanonicalName());
} catch (InstantiationException e) {
throw new RuntimeException("Failed to create an instance of "
+ klass.getCanonicalName());
}
}
Room has limited the use of reflection so the speed of the room is not affected much by reflection
Upvotes: 2
Reputation: 2864
Retrofit is used the Java Dynamic Proxy approach to create classes at runtime, and this requires an interface so you just need to define your Interface and retrofit will build a type-safe implementation of your interface at runtime.
Upvotes: 1
Reputation: 3186
They use two different approaches, Retrofit takes advantage of Java reflection proxy which is a tool to implement interfaces in runtime, your proxy's invoke
method will retrieve the called method scheme through reflection and can work based on that. In fact retrofit can work with method metadata only.
Proxy is a way to create objects from interfaces without implementing them using code, but by a single invoke method which simply gets these arguments
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Log.d("proxyCall", method.getName());
return Response (...);
}
You can get other info from method as well (like it's annotations e.g. @GET etc.)
On the other hand, Room uses annotation processors to generate code during compile time (you add it's processor a.k.a. compiler in the gradle configuration using annotationProcessor
or kapt
).
You can find the Room's generated source codes inside the build
folder of your module.
Upvotes: 3