Android:使用Guava加载跨库接口实现

2022-04-18 00:00:00 android java guava

我希望在我的Android应用程序中收集具体接口的所有实现。我有这样的东西:

            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());

但它总是返回0个类。即使我想检索所有类:

ClassPath.from(ClassLoader.getSystemClassLoader())
                    .getAllClasses()
                    .stream()
                    .map(ClassPath.ClassInfo::load)
                    .collect(Collectors.toList());

总是为零。当我在单元测试中从我的库本地运行它时,它是正常的。可能,这是ClassLoader的问题。它不提供有关应用程序提供的所有包的信息。

我不想使用DexFile,因为它是deprecated 。没有有关entries()替换函数的其他信息。

是否有可能解决此问题?


解决方案

TLDR:

您可以使用dagger依赖项(或更新,hilt)将组件安装到一个域中,例如SingletonComponent,并通过实现将其作为构造函数参数注入。您甚至可以按设置注入多个实现。

真实答案:

我已经创建库commontest。这些库固定在我的应用程序中。

  1. common模块中,您可以创建任何界面,如:
public interface Item {
}
  1. 将依赖项common设置为test。重新加载依赖项。现在您可以在test库中看到Item。编写实现接口的自定义类:
public class CustomItem implements Item{

//...

}
  1. test库中创建模块:
@Module
@InstallIn(SingletonComponent.class)
public class TestModule {

    @Provides
    @Singleton
    @IntoSet
    public Item customItem() {
        return new CustomItem();
    }

}
  1. 在应用程序中设置依赖项commontest,并使用您的实现集添加模块:
@Module
@InstallIn(SingletonComponent.class)
public class ApplicationSingletonModule {

    @Provides
    @Singleton
    public CustomClassProvider customClassProvider(Set<Item> items) {
        return new CustomClassProvider(items);
    }
}

您可以添加多个Item实现并将其跨库插入,没有任何问题。

相关文章