Cross module method invocation made easy
Are you building an Android App with multiple modules? If so, I guess you maybe facing the same problem as me, that is: Cross Module Method Invocation. It’s easy to call methods from library modules in our application module. But it’s annoying to invoke methods from the application module in our library modules.
Solution
In order to solve this problem, I wrote a simple tool called AppJoint. With AppJoint, now we can call any methods from any module in anywhere.
Assuming our project structure is like below:
1 | projectRoot |
Here, app is an application module and module1/module2 are library modules. app module depends on module1 and module2:
If we wish the app module to provide services to other modules like module1 and module2, we need to create a new library first and define service interfaces inside it and make all modules have the dependency of this new module.
For example, I create a new library module named service and create several kotlin interfaces which representing the services that each module wants to provide for other modules to use:
1 | projectRoot |
- Methods in
AppServiceare provided by theappmodule for other modules to use - Methods in
Module1Serviceare provided by themodule1module for other modules to use - Methods in
Module2Serviceare provided by themodule2module for other modules to use
All modules should include the service module excluding the service module itself:
1 | dependencies { |
Maybe our AppService.kt source codes are like below:
1 | interface AppService { |
And then we write an implementation of AppService in the app module:
1 |
|
Note that we add a @ServiceProvider annotation on the AppServiceImpl class.
Now, if we need to call methods of AppService inside module1 or module2, we just need to write codes as below:
1 | val appService = AppJoint.service(AppService::class.java) |
That’s all, the @ServiceProvider annotation and the AppJoint.service method are the only two API.
Getting started
It’s easy to include AppJoint.
- Add the AppJoint plugin dependency to the
build.gradlefile in project root:
1 | buildscript { |
- Add the AppJoint dependency to every module:
1 | dependencies { |
- Apply the AppJoint plugin to your main app module:
1 | apply plugin: 'com.android.application' |
Conclusion
Github of AppJoint: https://github.com/PrototypeZ/AppJoint
Have fun!