Japan Corporation in 2021 as a new graduate - In charge of Android application development for PayPay Flea Market - In the middle of migration from Paging2 to Paging3
RemoteMediator 2.Migrate PagedListAdapter to PagingDataAdapter 3.Migration of processing around State to loadStateFlow Official Documents:https://developer.android.com/topic/libraries/architecture/paging/v3-migration
- Summarized and shared the method of migration to Paging3 - Migrated from the screens having minimal impact on services - Migrated the original implementation relevant to State and performing refactoring at the same time
- Summarized and shared the method of migration to Paging3 - Migrated from the screens having minimal impact on services - Migrated the original implementation relevant to State and performing refactoring at the same time
Noted at the Time of Migration - Migrated from the screens that do not affect primary functions - Migration may cause malfunction - Saved the know-how through gradual migration
- Summarized and shared the method of migration to Paging3 - Migrated from the screens having minimal impact on services - Migrated the original implementation relevant to State and performing refactoring at the same time
- Summarized and shared the method of migration to Paging3 - Migrated from the screens having minimal impact on services - Migrated the original implementation relevant to State and performing refactoring at the same time
performed refactoring at the same time Points Noted at the Time of Migration - Efficient refactoring - Refactoring, which requires a lot of labor is difficult - Simultaneous confirmation that Paging, State, and DB behavior is correct
caused problems in migration - Fatal code that can occur easily but generates infinite API calls - Advantages and considerations for migrating State to LoadStateFlow
RemoteMediator 2.Migrate PagedListAdapter to PagingDataAdapter 3.Migration of processing around State to loadStateFlow Official Documents:https://developer.android.com/topic/libraries/architecture/paging/v3-migration
caused problems in migration - Fatal code that can occur easily but generates infinite API calls - Advantages and considerations for migrating State to LoadStateFlow
calls override suspend fun load(loadType: LoadType, state: PagingState<Int, Item>): MediatorResult { return try { withContext(Dispatchers.IO) { if (loadType == LoadType.PREPEND) return MediatorResult.Success(true) val response = fetchAndRegisterData() val endOfPaginationReached = response.data.isEmpty() MediatorResult.Success(endOfPaginationReached) } } catch (e: Exception) { MediatorResult.Error(e) } } OK Upward reading is Since there is no need for Success(true)
calls override suspend fun load(loadType: LoadType, state: PagingState<Int, Item>): MediatorResult { return try { withContext(Dispatchers.IO) { if (loadType == LoadType.PREPEND) return MediatorResult.Success(true) val response = fetchAndRegisterData() val endOfPaginationReached = response.data.isEmpty() MediatorResult.Success(endOfPaginationReached) } } catch (e: Exception) { MediatorResult.Error(e) } } OK Upward reading is Since there is no need for Success(true) Why is it necessary? 写真:アフロ
calls override suspend fun load(loadType: LoadType, state: PagingState<Int, Item>): MediatorResult { return try { withContext(Dispatchers.IO) { if (loadType == LoadType.PREPEND) return MediatorResult.Success(true) val response = fetchAndRegisterData() val endOfPaginationReached = response.data.isEmpty() MediatorResult.Success(endOfPaginationReached) } } catch (e: Exception) { MediatorResult.Error(e) } } OK Upward reading is Since there is no need for Success(true) Let’s have a look at the loading order 写真:アフロ
calls override suspend fun load(loadType: LoadType, state : PagingState<Int, Item>): MediatorResult { return try { withContext(Dispatchers.IO) { if (loadType == LoadType.PREPEND) return MediatorResult.Success(true) val response = fetchAndRegisterData() val endOfPaginationReached = response.data.isZeroMatch MediatorResult.Success(endOfPaginationReached) } } catch (e: Exception) { MediatorResult.Error(e) } } OK As PREPEND is not required at the time of downward loading, Success(true) is returned
caused problems in migration - Fatal code that can occur easily but generates infinite API calls - Advantages and considerations for migrating State to LoadStateFlow
- Information relevant to State can be acquired using loadStateListener - Leaving implementation of State for both DataBase and loadStateListener aside is not a good option as the implementation will be reviewed again in the future - Information about State and information about products were saved together in DataBase
data class Item( @PrimaryKey(autoGenerate = true) val id: Int, val title: String, val empty: Boolean = false ) Flag whether or not to display an indication of missing data
data class Item( @PrimaryKey(autoGenerate = true) val id: Int, val title: String, val empty: Boolean = false ) Converted to an object indicating that there was no data and Item and State were separated out.
the processes related to display such as State from DB 2.Aggregate State to Fragment 3.Migrate BoundaryCallback and other data acquisition processes 4.Managing the State on the basis of the loadStateFlow of PagingDataAdapter
the processes related to display such as State from DB 2.Aggregate State to Fragment 3.Migrate BoundaryCallback and other data acquisition processes 4.Managing the State on the basis of the loadStateFlow of PagingDataAdapter
the processes related to display such as State from DB 2.Aggregate State to Fragment 3.Migrate BoundaryCallback and other data acquisition processes 4.Managing the State on the basis of the loadStateFlow of PagingDataAdapter
View) : VH(view) class ZeroMatchViewHolder(view: View) :VH(view) } <ProgressBar android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center” /> Original implementation around DataBase that caused problems in migration
the processes related to display such as State from DB 2.Aggregate State to Fragment 3.Migrate BoundaryCallback and other data acquisition processes 4.Managing the State on the basis of the loadStateFlow of PagingDataAdapter
the processes related to display such as State from DB 2.Aggregate State to Fragment 3.Migrate BoundaryCallback and other data acquisition processes 4.Managing the State on the basis of the loadStateFlow of PagingDataAdapter
binding.loading.visibility = VISIBLE … } } Original implementation around DataBase that caused problems in migration Perform corresponding processing based on the LoadState status
caused problems in migration - Fatal code that can occur easily but generates infinite API calls - Advantages and considerations for migrating State to LoadStateFlow
into FragmentaIt becomes complicated when display is split on the basis of loading information of multiple APIs - LoadState is flowing in large quantities, so it is necessary to devise a way to narrow it down
to devise a way to narrow it down 13:41:34:046 LoadState: LoadType.Loading 13:41:34:411 LoadState: LoadType.Loading 13:41:34:531 LoadState: LoadType.Loading 13:41:34:652 LoadState: LoadType.Loading 13:41:34:657 LoadState: LoadType.Loading ・ ・ ・
as the benefits from new features, affinity with Coroutines Flow, provision of LoadState - We hope it will be useful in your projects! - I have introduced the knowledge gained in the current migration in PayPay Flea Market