Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: 2 aar libraries with the same package

Edit: A follow-up question based on this discussion was published in the following link.

Android: How to manage common codebase in multiple libraries used by the same application

I have two android aar library projects: LibA using ClassA, and LibB using ClassB. Both libs have the same base package. both libs use the same class named BaseClass, currently resides separately within each lib in package name 'common'. BaseClass contains one method named baseMethod.

This creates two libs using a class with the same name and a different implementation.

this is how the classes look like:

ClassA:

package mybasepackage.a;

import mybasepackage.common.BaseClass;

public class ClassA {

    BaseClass baseClass;

    public ClassA() {
        this.baseClass= new BaseClass();
    }

    public String myPublicMethod(){
        return this.baseClass.baseMethod();
    }
}

ClassB:

package mybasepackage.b;

import mybasepackage.common.BaseClass;

public class ClassB {

    BaseClass baseClass;

    public ClassB() {
        this.baseClass = new BaseClass();
    }

    public String myPublicMethod(){
        return this.baseClass.baseMethod();
    }
}

BaseClass In LibA:

package mybasepackage.common;

 public class BaseClass{

   public String baseMethod() {
        return "Called from ClassA";
    }
}

BaseClass in LibB:

package mybasepackage.common;

 public class BaseClass{

   public String baseMethod() {
        return "Called from ClassB";
    }
}

When I try to compile both libs in the same app, it throws a duplicated class error: "Program type already present: mybasepackage.common.BaseClass", this happens because the compiler cannot know which BaseClass to compile since it resides within both libs.

My goal is to allow both aar libs to compile successfully within the same app, while providing different implementations for the BaseClass. More formally, LibA and LibB should compile in the same application such as:

Calling new ClassA().baseMethod() will return "Called from ClassA".

Calling new ClassB().baseMethod() will return "Called from ClassB".

Pre condition: I cannot change the base package name in one of the libs because it essentially creates an unwanted duplication of BaseClass.

NOTE: I'm aware this may not be possible via the aar approach. If that is truly the case, I'm willing to consider other deployment architectures as long as I'll be able to compile these libs with the same common class using different implementations, as described in the question.

like image 290
Ariel Mann Avatar asked Aug 04 '19 13:08

Ariel Mann


People also ask

What is the difference between AAR and jar?

The main difference is aar is splitted inside android to jar. If your app will be used only in user app only in android studio then aar is preferred. If you are planning for app to communicate with c/c++ compiled lib.so file jar is preferred.

What is an Android shared library?

Description. A shared library or shared object is a file that is intended to be shared by multiple programs. Symbols used by a program are loaded from shared libraries into memory at load time or runtime.

How do I add AAR library?

Add your AAR or JAR as a dependency To use your Android library's code in another app module, proceed as follows: Navigate to File > Project Structure > Dependencies. In the Declared Dependencies tab, click and select Jar Dependency in the dropdown. In the Add Jar/Aar Dependency dialog, first enter the path to your .


Video Answer


2 Answers

My goal is to allow both aar libs to compile successfully within the same app, while providing different implementations for the BaseClass

That is not possible, sorry.

I'm aware this may not be possible via the aar approach.

It has nothing to do with AARs. You cannot have two classes with the same fully-qualified class name in the same app, period. It does not matter where those duplicate classes come from.

I'm willing to consider other deployment architectures as long as I'll be able to compile these libs with the same common class using different implementations, as described in the question.

That is not possible, sorry. Again: it does not matter where the duplicate classes come from. You simply cannot have duplicate classes.

like image 152
CommonsWare Avatar answered Oct 16 '22 10:10

CommonsWare


Given your precondition you just can't do that in this way. You cannot have 2 different libraries in java with the same package name, which is the main problem that throws your error (and not the name of the classes).

What you can do and maybe if possible is the best way to handle with that is to merge the two libraries into just one and add two subpackages inside and then just import them:

import mybasepackage.common.a_name.BaseClass; // class A
import mybasepackage.common.b_name.BaseClass; // class B

This will prevent the duplication error because they just have the same name but from different packages.

Another idea if this way doesn't fit your expectation is to change the architecture by implementing another abstraction layer in which you define your BaseClass as an abstract method:

package mybasepackage.common;

 public class abstract BaseClass{

   public String myPublicMethod();
 }

and then you just implement the method inside ClassA and ClassB:

public class ClassA implements BaseClass{

    public ClassA() {
        super();
    }

    @Override
    public String myPublicMethod(){
        // logic for A
    }
}

NB note that the above implementation of class A is just a stub and it is not supposed to work as it is. Adapt to your need.

In any case by the way you can't have two packages with same classes name.

like image 41
Thecave3 Avatar answered Oct 16 '22 12:10

Thecave3