Я не знаю, как вызвать или использовать хранилище данных, кроме как в модели представления.
Я хочу использовать значение токена из хранилища данных, чтобы сохранить значение, оно работает, но когда я вызываю хранилище данных в файл 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)
Никогда не следует создавать 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
}
Вставьте ошибку в виде текста и удалите скриншот.