"PagingSource"中的"无效"是最终的,不能被覆盖[Android Kotlin]?



我刚刚开始在android开发。我在github上看到一个使用Retrofit调用Deezer Api的项目,我想将其实现到我的项目中,但我在PagingSource类中遇到了麻烦,这里是PagingSource类:

package com.example.myapplication.data.remote.paging
import androidx.paging.PagingSource
import com.example.myapplication.data.models.ResponseData
import com.example.myapplication.data.models.album.Album
import com.example.myapplication.data.models.artist.Artist
import com.example.myapplication.data.models.tracks.Track
import com.example.myapplication.data.remote.paging.PagingDataSource
import com.example.myapplication.data.services.ServiceType
import retrofit2.HttpException
import java.io.IOException
abstract class PagingRepository(
private val query: String,
private val serviceType: ServiceType,
private val pagingDataSource: PagingDataSource
) : PagingSource<Int, ResponseData>() {
companion object {
private val inMemoryCache =
mutableListOf<ResponseData>() // (*) we don't care about the object type
private val queryCache = mutableListOf<String>()
}

private val startPage = 0
private val limit = 25

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ResponseData> {
val position = params.key ?: startPage
val apiQuery = query
return try {

val oldQuery = queryCache.find {
apiQuery.equals(it, true)
}

if (oldQuery != null && position == startPage) {
val validatedResults = resultsValidatedAndSorted(apiQuery)
LoadResult.Page(
data = validatedResults,
prevKey = null,
nextKey = null
)
} else {
val response = when (serviceType) {
ServiceType.Artists -> pagingDataSource.fetchArtist(apiQuery, position * limit, limit)
ServiceType.Albums -> pagingDataSource.fetchAlbum(apiQuery, position * limit, limit)
ServiceType.Tracks -> pagingDataSource.fetchTrack(apiQuery, position * limit, limit)
}
val body = response.body()!!
val results = response.body()!!.data

queryCache.add(apiQuery)

val shelled = results.map { ResponseData(query = apiQuery, data = it) }

inMemoryCache.addAll(
shelled
)

LoadResult.Page(
data = if (position * limit <= body.total) shelled else emptyList(),
prevKey = if (position == startPage) null else position - 1,
nextKey = if (shelled.isEmpty() || position * limit > body.total) null else position + 1
)
}

} catch (exception: IOException) {
return LoadResult.Error(exception)
} catch (exception: HttpException) {
return LoadResult.Error(exception)
}
}

private fun resultsValidatedAndSorted(query: String): List<ResponseData> {
return inMemoryCache.filter {
it.query.contains(query, true)
}
}

override fun invalidate()
{
super.invalidate()
inMemoryCache.clear()
queryCache.clear()
}
}

误差: 'invalidate'在'PagingSource'中是最终的,不能被重写

我的gradle文件:

plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.gms.google-services'
id 'kotlin-kapt'
id 'kotlin-android'
id 'com.google.dagger.hilt.android'
id 'androidx.navigation.safeargs.kotlin'
id 'kotlin-parcelize'
}
android {
namespace 'com.example.myapplication'
compileSdk 33
defaultConfig {
applicationId "com.example.myapplication"
minSdk 33
targetSdk 33
versionCode 1
versionName "1.0"
// buildToolsVersion "30.0.2"
def secureProps = new Properties()
if (file("../secure.properties").exists()) {
file("../secure.properties")?.withInputStream { secureProps.load(it) }
}
vectorDrawables.useSupportLibrary = true
buildConfigField "String", "BASE_URL", (secureProps.getProperty("BASE_URL") ?: "")
buildConfigField "String", "SECRET", (secureProps.getProperty("SECRET") ?: "")

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn"] // opt in for experimental functions
jvmTarget = '1.8'
}
buildFeatures {
viewBinding = true
dataBinding = true
}
}
dependencies {
implementation 'androidx.work:work-runtime-ktx:2.8.1'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.firebase:firebase-firestore-ktx:24.4.5'
implementation platform('com.google.firebase:firebase-bom:31.3.0')
implementation 'com.google.firebase:firebase-analytics-ktx:21.2.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
//paging
implementation 'androidx.paging:paging-common-ktx:3.1.1'
implementation 'androidx.paging:paging-runtime-ktx:3.0.0-alpha10'
//navigation
def nav_version ="2.5.3"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
//coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
// - - ViewModel
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
//glide
implementation 'com.github.bumptech.glide:glide:4.15.1'
kapt 'com.github.bumptech.glide:compiler:4.15.1'
//bottomNavigation
implementation 'com.google.android.material:material:1.8.0'
//splashscreen
implementation 'androidx.core:core-splashscreen:1.0.0'
// -- retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
// Lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
//implementation "androidx.lifecycle:lifecycle-runtime:2.6.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"

// HILT
def hilt_version = "2.45"
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

"androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "androidx.hilt:hilt-compiler:1.0.0"
// Timber
implementation 'com.jakewharton.timber:timber:5.0.1'
// ExoPlayer
api "com.google.android.exoplayer:exoplayer-core:2.18.5"
api "com.google.android.exoplayer:exoplayer-ui:2.18.5"
api "com.google.android.exoplayer:extension-mediasession:2.18.5"

// Firebase
implementation 'com.google.firebase:firebase-firestore:24.4.5'

// Firebase Storage KTX
implementation 'com.google.firebase:firebase-storage-ktx:20.1.0'

// Firebase Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4'



implementation 'androidx.media:media:1.6.0'

implementation 'com.google.firebase:firebase-analytics-ktx:21.2.1'
// Coil Image Loading Library
implementation('io.coil-kt:coil:1.1.0')
// Subtitle supported collapsing toolbar
implementation 'com.hendraanggrian.material:collapsingtoolbarlayout-subtitle:1.1.0'

// Flow Binding
implementation 'io.github.reactivecircus.flowbinding:flowbinding-android:0.10.2'

implementation('androidx.preference:preference-ktx:1.1.1')
}
kapt {
correctErrorTypes = true
}

但是当我删除覆盖fun invalidate()到fun invalidate()它有另一个错误:"'invalidate'隐藏超类型'PagingSource'的成员,需要'override' modifier">

所以这种行为的原因是PagingSource是抽象的。它是这样声明的:

public abstract class PagingSource<Key : Any, Value : Any> {

不能从抽象类中创建对象。

所以如果你想调用invalidate,它被解释为一个final(静态)方法。你不能推翻期末考试。但是如果你不写override修饰符,你就对PagingSource隐藏了invalidate函数。这是不允许的。

确切地说。fun invalidate应该被声明为abstract fun invalide(),那么你必须通过重写来实现这个函数。

但是invalidate()是这样声明的,PagingSource是这样实现的

public fun invalidate() {
// implementation
}

我无法解决你的代码,因为我不知道什么时候应该发生什么等等。如果你只需要一个invalidate语句,你可以这样调用:

pagingRepository.invalidate()

然后创建另一个函数,像这样

pagingRepository.invalidatePaging()

fun invalidatePager() {
this.invalidate() // this should have the same effect like your planned override
inMemoryCache.clear()
queryCache.clear()
} 

但是我对你的例子的代码和架构了解得不够。如果你想深入研究,那就做一个关于分页的谷歌实验室。

最新更新