'invalidate' in 'PagingSource' is final and cannot be overrided [AndroidKotlin]?

lndjwyie  于 2023-04-07  发布在  Kotlin
关注(0)|答案(1)|浏览(175)

我刚开始做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()
    }

}

错误:“PagingSource”中的“invalidate”是最终的,不能被覆盖

这里是我的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 invalid()移到fun invalid()时,它又出现了另一个错误:“'invalidate'隐藏超类型'PagingSource'的成员,需要'override'修饰符”

odopli94

odopli941#

因此,这种行为的原因是PagingSource是抽象的。它的声明如下:

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

抽象类you can not create a object.
所以如果你想调用invalidate,它会被解释为final(静态)方法。你不能覆盖finals。但是如果你不写override修饰符,你就对PagingSource隐藏了invalidate函数。这是不允许的。
fun invalidate应该声明为abstract fun invalide(),然后必须通过override实现该函数。
但是invalidate()是这样声明的,并且是PagingSource中的一个真实的实现

public fun invalidate() {
   // implementation
 }

我不能解决你的代码,因为我不知道什么时候会发生什么等等。如果你只是需要一个无效,你可以这样调用:
pagingRepository.invalidate()
然后创建另一个类似这样的函数
pagingRepository.invalidatePaging()

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

但是我对你的例子的代码和架构了解的不够多,如果你想深入研究,那就去google实验室看看分页。

相关问题