'Android: Load implementations of interface across libraries using Guava
I want to collect all implementations of concrete interface in my Android application. I've got something like this:
List<T> list = ClassPath.from(ClassLoader.getSystemClassLoader())
.getTopLevelClasses(Reflection.getPackageName(parent))
.stream()
.map(ClassPath.ClassInfo::load)
.filter(current -> isImplementation(parent, current))
.map(aClass -> (T) aClass)
.collect(Collectors.toList());
but It always return 0 classes. Even if I want to retrieve all classes:
ClassPath.from(ClassLoader.getSystemClassLoader())
.getAllClasses()
.stream()
.map(ClassPath.ClassInfo::load)
.collect(Collectors.toList());
It's always zero. When I run it locally from my library in unit test it's ok. Probably, it's problem with ClassLoader. It doesn't provide informations about all packages provided by application.
I don't want to use DexFile because it's deprecated . There's no other information about entries() replacement function.
Is there any possibility to work around this?
Solution 1:[1]
TLDR:
You can use dagger dependency (or newer, hilt) to install components into one domain, such as SingletonComponent and inject it as constructor parameter by implementation. You can even inject multiple implementations as set.
Real answer:
I have created library common and test. Those libraries are pinned in my application.
- In
commonmodule you can create any interface, like:
public interface Item {
}
- Set dependency
commontotest. Reload dependencies. Now you can seeItemin yourtestlibrary. Write custom class that implements interface:
public class CustomItem implements Item{
//...
}
- Create module in your
testlibrary:
@Module
@InstallIn(SingletonComponent.class)
public class TestModule {
@Provides
@Singleton
@IntoSet
public Item customItem() {
return new CustomItem();
}
}
- Set dependency
commonandtestin application and add module with set of your implementations:
@Module
@InstallIn(SingletonComponent.class)
public class ApplicationSingletonModule {
@Provides
@Singleton
public CustomClassProvider customClassProvider(Set<Item> items) {
return new CustomClassProvider(items);
}
}
You can add multiple Item implementations and inject it across libraries without any problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | KurdTt- |
