Как использовать хранилище данных для сохранения токена

Я не знаю, как вызвать или использовать хранилище данных, кроме как в модели представления.

Я хочу использовать значение токена из хранилища данных, чтобы сохранить значение, оно работает, но когда я вызываю хранилище данных в файл MainRemote.kt, возникает проблема, я знаю только, как использовать его в модели представления.

этот код в моем MainRemote.kt

class MainRemote() {
    var authDataStorePreferences = ConnectionReleaseApplication().authDataStorePreferences
    init {

    }

    val client = HttpClient(CIO) {
        defaultRequest {
            url(host = BuildConfig.apiDomain, port = 3000)
            contentType(ContentType.Application.Json)
        }

        install(Auth){
            bearer {
                loadTokens {
                    BearerTokens("token","mklklkl")
                }
            }
        }
        install(ContentNegotiation) {
            json(
                Json {
                    prettyPrint = true
                    isLenient = true
                    ignoreUnknownKeys = true

                }
            )
            install(Logging) {
                logger = Logger.ANDROID
                level = LogLevel.BODY
            }
        }


    }
}

этот код, когда я регистрирую хранилище данных в файле ConnectionReleaseApp.kt

private const val AUTH_PREFERENCES_NAME = "auth_preferances_name"
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = AUTH_PREFERENCES_NAME)

class ConnectionReleaseApplication : Application() {
    lateinit var authDataStorePreferences: AuthDataStorePreferences

    override fun onCreate() {
        super.onCreate()
        authDataStorePreferences = AuthDataStorePreferences(dataStore)
    }
}

Ошибка в моем логарифме

kotlin.UninitializedPropertyAccessException: lateinit property authDataStorePreferences has not been initialized
                                                                                                        at com.example.connectionmobile.ConnectionReleaseApplication.getAuthDataStorePreferences(ConnectionReleaseApplication.kt:14)
                                                                                                        at com.example.connectionmobile.api.remote.MainRemote.<init>(MainRemote.kt:22)
                                                                                                        at com.example.connectionmobile.api.repository.AuthRepository.login(AuthRepository.kt:12)
                                                                                                        at com.example.connectionmobile.viewModel.LoginViewModel.login(LoginViewModel.kt:55)
                                                                                                        at com.example.connectionmobile.ui.screen.LoginScreenKt$LoginScreen$1$4$1.invokeSuspend(LoginScreen.kt:77)
                                                                                                        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                                                                        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:68)
                                                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1542)
                                                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1553)
                                                                                                        at android.view.Choreographer.doCallbacks(Choreographer.java:1109)
                                                                                                        at android.view.Choreographer.doFrame(Choreographer.java:984)
                                                                                                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1527)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:257)
                                                                                                        at android.os.Looper.loop(Looper.java:368)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8826)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:572)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)

введите сюда описание изображения

Вставьте ошибку в виде текста и удалите скриншот.

Leviathan 31.05.2024 02:24
0
1
83
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Никогда не следует создавать Application и Activity непосредственно из конструктора, как вы это делали с ConnectionReleaseApplication(), потому что они будут созданы системой Android, поэтому функция onCreate() не будет выполняться, если вы создаете их напрямую.

Что вы можете сделать, передать экземпляр DataStore вашему конструктору MainRemote вот так

class MainRemote(private val authDataStorePreferences: AuthDataStorePreferences) {
    // ...
}

Затем в тех местах, где вы создаете MainRemote, передайте экземпляр DataStore внутри конструктора, предполагая, что вы создадите его внутри составной функции.

@Composable
fun Somewhere() {
    val context = LocalContext.current
    val mainRemote = remember {
        val application = (context.applicationContext as ConnectionReleaseApplication)
        MainRemote(application.authDataStorePreferences)
    }
}

Если вы не добавили ConnectionReleaseApplication в свой AndroidManifest.xml, вам следует сделать это, чтобы система создала его за вас.

<application
    android:name = ".ConnectionReleaseApplication"

    >

Обратите внимание: хотя приведенное выше решение будет работать, это не рекомендуется. Вместо этого вам следует научиться использовать такие шаблоны, как Dependency Injection и ViewModel.

Ответ принят как подходящий

Всегда используйте Hilt для управления внедрением зависимостей в приложении Android. Чтобы сделать экземпляр DataStore доступным для любого компонента или класса, вы можете написать модуль hilt:

@InstallIn(SingletonComponent::class)
@Module
object DataStoreModule {

    @Binds
    @Singleton
    fun provideAuthPreference(
        dataStore: DataStore<Preferences>
    ): AuthDataStorePreferences = AuthDataStorePreferences(dataStore)

    @Provides
    @Singleton
    fun providePreferenceDataStore(@ApplicationContext context: Context): DataStore<Preferences> {
        return PreferenceDataStoreFactory.create {
            context.preferencesDataStoreFile("auth_preferances_name")
        }
    }
}

а затем в вашем MainRemote классе:

class MainRemote() {
    @Inject
    lateint var authDataStorePreferences: AuthDataStorePreferences
    
    //rest of the code 
}

  • Подробнее о рукоятке читайте в официальной документации.

Другие вопросы по теме