Android Hilt provide object with dynamic property

346 views Asked by At

I am using PagingSource. From the official doc here is an example of paging source class implementation.

class ExamplePagingSource(
    val backend: ExampleBackendService,
    val query: String
) : PagingSource<Int, User>() {
........
........

In ViewModel i have setup flow of paging data this way

val flow = Pager(
  PagingConfig(pageSize = 20)
) {
  ExamplePagingSource(backend, query)
}.flow
  .cachedIn(viewModelScope)

Now if I want Hilt to provide ExamplePagingSource dependency how can I do that?

ExamplePagingSource took query in the constructor which changes every search action, I always have to provide a new instance of ExamplePagingSource.

One way could be to initialize ExamplePagingSource with ExampleBackendService and set query by setter every time. But this will not work if I call PagingDataAdapter.refresh() for swipe refresh action and it throws exception

java.lang.IllegalStateException: An instance of PagingSource was re-used when Pager expected to create a new instance.Ensure that the pagingSourceFactory passed to Pager always returns a new instance of PagingSource.

So how can I config Hilt so that Hilt can provide ExamplePagingSource as a dependency

1

There are 1 answers

0
Jan Bína On

You can make use of dagger's assisted injection. The query will be @Assisted and you will have to pass it to create function, but ExampleBackendService and everything else will be provided by dagger.

class ExamplePagingSource @AssistedInject constructor(
    val backend: ExampleBackendService,
    @Assisted val query: String
)

@AssistedFactory
interface ExamplePagingSourceFactory {
    fun create(query: String): ExamplePagingSource
}

@HiltViewModel
class ExampleViewModel @Inject constructor(
    private val exaplePagingSourceFactory: ExamplePagingSourceFactory,
) : ViewModel() {
    val flow = Pager(PagingConfig(pageSize = 20)) {
        exaplePagingSourceFactory.create(query)
    }
}