OtienoSamwel
OtienoSamwel

Reputation: 426

Interface in Room and Retrofit

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

Answers (3)

Thang Nguyen Van
Thang Nguyen Van

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

Jimale Abdi
Jimale Abdi

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

Amin
Amin

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

Related Questions