Csabi
Csabi

Reputation: 3043

How can I acces Activity from AAR emded into another AAR?

How can I access Activity from AAR library which is not directly included into the project but is embed to another AAR library?

I got an error java.lang.NoClassDefFoundError: Failed resolution of: The class is public and if I compile it directly in project application it can be used without problem.

I included an AAR to my project like this :

ProjectApplication
  |
  +--sharedModule (android library - AAR or any working solution)
  |      |
  |      +--Module1 (android library - AAR or any working solution)
  |      |
  |      +--Module2 (android library - AAR or any working solution)
  |      |
  |      +--Module3 (android library - AAR or any working solution)


 compile (project(":sharedFrameWork")){ transitive = true }

which has also included in itself 2 other AAR libs. They are also set to be Transitive. When I try to open an activity from one of the sub AAR libraries. I got the class not found error. But when I include that particular AAR into my application directly the class is found and can be used. It looks like I do not have access to any sub AAR libraries which are not included directly into my Application.

To better describe my situation :

I have to create an integration AAR library (later called 'sharedFrameWork') which includes multiple AAR libraries and is later embed into an application.

Multiple AAR -> Shared AAR 'sharedFrameWork' -> Application

The sharedFrameWork has some method which starts some activities from the included AAR's or set up basic communication with the server. I have read that if all the dependencies are set to be transitive it will make it work, but unfortunately it does not. So When I call from my application a method which should start an activity from one of the included AAR in sharedFrameWork the app reports me that no such a class was found. But when I include that AAR module right to my application not to sharedFrameWork, and then call the exact same functionality the Class is found and the project is working as it is designed. Can you help me how can I create this sharedFrameWork to be working as it is designed? Can it be done by using AAR or should I take another approach? If any other way it can be done and the result will be that I can deliver just one library and it will work as designed so it can access its submodules I will go with it, feel free to point me out the best approach for this problem.

Upvotes: 1

Views: 829

Answers (1)

Fco P.
Fco P.

Reputation: 2691

If I get it right, you want to create a fat AAR and achieve a single import of several libraries.

Now, since you haven't provided more info, I'm going to assume you are using gradle 2. In gradle 2, submodules don't share their dependencies. neither does anything you put into the libs folder. So, first, I would upgrade your projects to gradle 3, switch from "compile" command to "api" command, and check. If that does not work, the next step would be to apply the gradle maven plugin to each one of your modules, and deploy the resultant AAR file to either your local maven repo (automatically created when you install maven), or a remote repo, like jitpack. If you have AARs/JARs into the libs folder, deploy them to a repo too and import them from there (libs folder scope is local in gradle 2, and in general, is a bad idea to use it instead of a centralized repo. You can even use github as a repo). Then, use the artifacts. Finally, the last solution for your problem would be to use "shading"; the process to pack several different artifacts into one. If you can't upgrade to gradle 3, or deploy the artifacts somewhere (unlikely), this is what you should do. There are several plugins for this:

https://plugins.gradle.org/search?term=shade

https://github.com/zawn/android-shade-plugin

if those don't work for you, switch to maven and use the maven shade plugin.

As a side note, you should not provide a fat AAR. Is better to keep your framework in separate modules. That will speed up your build process and allow you to save space if you don't require some classes. Even in a multimodule project, you can create separate artifacts, one for each module, and import them as you need. Just avoid circular references (a module A that requires a module B which requires module C which requires module A) and you'll be fine.

Upvotes: 1

Related Questions