将数据传递给 PageKeyedDataSource

Soo*_*tos 12 paging android dagger-2

我正在使用PageKeyedDataSource通过调用 API 和使用 Retrofit 进行分页。

我正在使用Dagger 2进行依赖注入。

@Provides
Repository provideRepository(...) {
    ...
}

@Provides
PageKeyedVideosDataSource providePageKeyeVideosDataSource(Repository repository) {
    ...
}

@Provides
VideoDataSourceFactory provideVideoDataSourceFactory(PageKeyedHomeVideosDataSource pageKeyedHomeVideosDataSource) {
    ...
}

@Provides
ViewModelFactory provideViewModelFactory(Repository repository, VideoDataSourceFactory videoDataSourceFactory) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在,我需要做同样的事情,但是我的调用需要一个新参数:一个 id。

@GET(Urls.VIDEOS_BY_CATEGORY)
    Observable<RequestVideo> getVideosByCategory(
            @Path("id") int categoryId,  // <-- Now I need this new parameter
            @Query("per-page") int perPage,
            @Query("page") int page);
Run Code Online (Sandbox Code Playgroud)

之前,我的 PageKeyedVideosDataSource 只需要页面和每页就可以进行调用,这很容易。但是,现在我需要将这个新参数 id 动态地放入 PageKeyedDataSource 中。

我看到了PagingWithNetworkSample并发现他们通过在构造函数中添加它在 PagedKeyedDataSource 中放置了一个新参数。然后,我想这样做:

public PageKeyedCategoryVideosDataSource(int categoryId, Repository repository) {
    this.categoryId = categoryId;
    this.repository = repository;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在构造函数中添加 id,我想我将无法再使用 dagger 2,因为通过使用 dagger 2,PageKeyedVideosDataSource 不是动态创建的,因此,我无法继续更改 id 的值。

我需要像这样动态创建 PageKeyedDataSource:

int categoryId = getCategoryId();
PageKeyedVideosDataSource dataSource = new PageKeyedVideosDataSource(categoryId, repository);
Run Code Online (Sandbox Code Playgroud)
  • 我应该这样做而不是使用 Dagger 2 吗?
  • 是否可以仍然使用 Dagger 2 动态创建数据源?

mly*_*yko 2

虽然回答晚了,也许可以帮助其他人。

当您需要将“动态”参数传递到 dagger 的图表中时,dagger 无法创建依赖项的实例。在这种情况下,dagger 将为您的 PageKeyedVideosDataSource 提供 Factory,但您必须手动将参数传递到构造函数中。

你会有工厂(kotlin 示例,但也可以在 java 中工作):

class PageKeyedVideosDataSourceFactory @Inject constructor(
  private val repository: Repository
) {
  
  fun create(categoryId: Int): PageKeyedVideosDataSource {
   return PageKeyedVideosDataSource(categoryId, repository)
  }

}
Run Code Online (Sandbox Code Playgroud)

然后,您无需注入实例,而是注入PageKeyedVideosDataSourceFactory工厂并手动调用factory.create(categoryId)它。

如果您想自动创建工厂,您可以检查AssistedInject 库(来自 Square),它可以创建工厂的实现。