Status Update
Comments
an...@outlook.com <an...@outlook.com> #2
Branch: androidx-master-dev
commit c60f33e229e31ab328ef6b59dab63b264954831c
Author: Alexandre Elias <aelias@google.com>
Date: Fri Jul 10 16:23:09 2020
Semantics no-op cleanups
Partly in response to lmr's broad code review, I did a pass of
superficial API/implementation cleanup. The main changes are:
- I changed each Boolean SemanticsProperty where false is equivalent to
not being present to take "Unit" instead. This is conceptually
clearer: it avoids questions like "can I cancel out a semantics from a
merged child by setting it to false?" Because "property = Unit" looks
weird, I also changed the style of these to "property()".
- I moved the Semantics id generator closer to where it's used, in
SemanticsModifierCore. I made it internal and an AtomicInt.
(Note that integer ids are heavily used in the Android
AccessibilityNodeInfo APIs so I can't simply remove them entirely.)
- I deleted dead code. Some examples include SemanticsHintOverrides,
a public API not connected to anything, and SemanticsPropertyKey
merge() open method which is never called. (In both cases I have
a different plan in mind for accessibility.)
Fixes: 145951226
Fixes: 145955412
Test: existing tests
Relnote: "Single-value semantics properties now use a calling style.
For example, 'semantics { hidden = true }' is now written as:
'semantics { hidden() }'."
Change-Id: Ic1afd12ea22c926babc9662f1804d80b33aa0cfc
M ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/LayoutNodeModifierBenchmark.kt
M ui/ui-core/api/0.1.0-dev15.txt
M ui/ui-core/api/current.txt
M ui/ui-core/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-core/api/public_plus_experimental_current.txt
M ui/ui-core/api/restricted_0.1.0-dev15.txt
M ui/ui-core/api/restricted_current.txt
M ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/graphics/vector/VectorTest.kt
M ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/semantics/SemanticsTests.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidActuals.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidComposeView.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidComposeViewAccessibilityDelegateCompat.kt
M ui/ui-core/src/androidMain/kotlin/androidx/ui/core/AndroidPopup.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/Expect.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsConfiguration.kt
D ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsHintOverrides.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsModifier.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsOwner.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsWrapper.kt
M ui/ui-core/src/commonMain/kotlin/androidx/ui/semantics/SemanticsProperties.kt
M ui/ui-foundation/api/0.1.0-dev15.txt
M ui/ui-foundation/api/current.txt
M ui/ui-foundation/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-foundation/api/public_plus_experimental_current.txt
M ui/ui-foundation/api/restricted_0.1.0-dev15.txt
M ui/ui-foundation/api/restricted_current.txt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Selectable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/selection/Toggleable.kt
M ui/ui-foundation/src/main/java/androidx/ui/foundation/semantics/FoundationSemanticsProperties.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/CardTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxScreenshotTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/RadioButtonScreenshotTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/ripple/RippleIndicationTest.kt
M ui/ui-material/src/androidTest/java/androidx/ui/material/textfield/TextFieldScreenshotTest.kt
M ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
M ui/ui-material/src/main/java/androidx/ui/material/TextFieldImpl.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/AssertsTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/CallSemanticsActionTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/FindersTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/PrintToStringTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/ScrollToTest.kt
M ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt
M ui/ui-test/src/main/java/androidx/ui/test/Actions.kt
M ui/ui-test/src/main/java/androidx/ui/test/Filters.kt
M ui/ui-text/api/0.1.0-dev15.txt
M ui/ui-text/api/current.txt
M ui/ui-text/api/public_plus_experimental_0.1.0-dev15.txt
M ui/ui-text/api/public_plus_experimental_current.txt
M ui/ui-text/api/restricted_0.1.0-dev15.txt
M ui/ui-text/api/restricted_current.txt
M ui/ui-text/src/commonMain/kotlin/androidx/ui/text/CoreTextField.kt
M ui/ui-text/src/commonMain/kotlin/androidx/ui/text/TextSemanticsProperties.kt
ro...@google.com <ro...@google.com> #3
js...@gmail.com <js...@gmail.com> #4
I have the same problem using alpha02 and it happens every time that I try to write to different keys at the same time.
I have tried forcing the same thread for both write operations and I still get this exception.
jo...@basetis.com <jo...@basetis.com> #5
I have tested alpha04 and it also occurs.
ro...@google.com <ro...@google.com> #6
Would one of you be able to share a code snippet that reproduces this?
Jordi, are you certain that you only have a single instance of DataStore open for your preferences?
ro...@google.com <ro...@google.com> #7
Also can you share how you forced both writes to happen on the same thread?
ra...@gmail.com <ra...@gmail.com> #8
im using this function on onViewCreated
here's my function to check if there is datastored in jetpack datastore
an...@outlook.com <an...@outlook.com> #9
in App.kt class fun getUserPreferences(): UserDataStorePreferences = UserDataStorePreferences(instance)
in Fragment :
signInViewModel.saveToken(it.data.token)
signInViewModel.saveRefreshToken(it.data.refreshToken)
in Repository:
CoroutineScope(Dispatchers.IO).launch {
App.getUserPreferences().saveRefreshToken(refreshToken)
}
ahd here's my datastore class:
package com.montymobile.sands.common
import android.content.Context
import androidx.datastore.DataStore
import androidx.datastore.preferences.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import java.io.IOException
class UserDataStorePreferences(
context: Context
) {
private val applicationContext = context.applicationContext
private val dataStore: DataStore<Preferences>
init {
dataStore = applicationContext.createDataStore(
name = "sns_preferences"
)
}
val getToken: Flow<String?>
get() = dataStore.data.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
preferences[KEY_TOKEN]
}
suspend fun saveTokens(token: String, refreshToken: String) {
dataStore.edit { preferences ->
preferences[KEY_TOKEN] = token
preferences[KEY_REFRESH_TOKEN] = refreshToken
}
}
val getDeviceId: Flow<String?>
get() = dataStore.data.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
preferences[KEY_DEVICE_ID]
}
suspend fun saveDeviceId(deviceId: String) {
dataStore.edit { preferences ->
preferences[KEY_DEVICE_ID] = deviceId
}
}
val getAppVersion: Flow<String?>
get() = dataStore.data.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
preferences[KEY_APP_VERSION]
}
suspend fun saveAppVersion(bookmark: String) {
dataStore.edit { preferences ->
preferences[KEY_APP_VERSION] = bookmark
}
}
val getRefreshToken: Flow<String?>
get() = dataStore.data.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
preferences[KEY_REFRESH_TOKEN]
}
suspend fun saveRefreshToken(refreshToken: String) {
dataStore.edit { preferences ->
preferences[KEY_REFRESH_TOKEN] = refreshToken
}
}
val isLoggedIn: Flow<Boolean?>
get() = dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
preferences[KEY_LOGGED_IN]
}
suspend fun setLoggedIn(loggedIn: Boolean) {
dataStore.edit { preferences ->
preferences[KEY_LOGGED_IN] = loggedIn
}
}
suspend fun clearTokens() {
dataStore.edit { preferences ->
preferences.remove(KEY_TOKEN)
preferences.remove(KEY_REFRESH_TOKEN)
}
}
companion object {
val KEY_TOKEN = preferencesKey<String>("key_token")
val KEY_DEVICE_ID = preferencesKey<String>("key_device_id")
val KEY_APP_VERSION = preferencesKey<String>("key_app_version")
val KEY_REFRESH_TOKEN = preferencesKey<String>("key_refresh_token")
val KEY_LOGGED_IN = preferencesKey<Boolean>("key_logged_in")
}
}
an...@outlook.com <an...@outlook.com> #10
suspend fun saveToken(token: String) {
dataStore.edit { preferences ->
preferences[KEY_TOKEN] = token
}
}
with
suspend fun saveTokens(token: String, refreshToken: String) {
dataStore.edit { preferences ->
preferences[KEY_TOKEN] = token
preferences[KEY_REFRESH_TOKEN] = refreshToken
}
}
ap...@google.com <ap...@google.com> #11
Branch: androidx-master-dev
commit ed6cbe16562eead7dd1a0042033d9386e686abfb
Author: rohitsat13 <rohitsat@google.com>
Date: Tue Nov 24 11:57:06 2020
Added a better exception and documentation so people ensure that there is only a single instance of DataStore per file.
In
Test: Added new test for concurrent writes from different DataStore.
Bug: 173522155
Relnote: Add a better documentation and exception around concurrent writes from datastores.
Change-Id: Ia98a2c42d9a43bab2af0672f52b8786fe854cdfd
M datastore/datastore-core/src/main/java/androidx/datastore/core/DataStoreFactory.kt
M datastore/datastore-core/src/main/java/androidx/datastore/core/SingleProcessDataStore.kt
M datastore/datastore-preferences-core/src/main/java/androidx/datastore/preferences/core/PreferenceDataStoreFactory.kt
M datastore/datastore-preferences/src/main/java/androidx/datastore/preferences/PreferenceDataStoreFactory.kt
M datastore/datastore/src/main/java/androidx/datastore/DataStoreFactory.kt
ro...@google.com <ro...@google.com> #12
Thanks for sharing. I believe what is happening is that you have multiple instances of DataStore open at the same time and they are writing concurrently. When you call DataStore.updateData
it writes to a temp file, then renames the temp file to the actual file name. Since you have two DataStore's writing at the same time, one of the renames seems to be failing (because the file no longer exists).
Each time you call context.createDataStore
it creates a new instance of DataStore (it's not like context.getSharedPreferences
).
You should instead create the DataStore once, then inject the instance where necessary or manage it as a singleton.
If you only have a single instance of DataStore open, then it'll handle the concurrency for you.
js...@gmail.com <js...@gmail.com> #13
I can confirm that in my case I had multiple instances. Now, reusing the same instance it works.
ro...@google.com <ro...@google.com> #14
Thanks, Marking this as fixed assuming that the others had the same problem. We are working on a better way of catching these scenarios.
Description
After starting my app, I encountered another issue. I found that Proto library is not found in the alpha-03 version so I rolled back to version alpha-01. Also, I tried alpha-02. Since then I am having the error below:
Process: com.montymobile.sands, PID: 19928
java.io.IOException: /data/user/0/com.montymobile.sands/files/datastore/sns_preferences.preferences_pb.tmp could not be renamed to /data/user/0/com.montymobile.sands/files/datastore/sns_preferences.preferences_pb
at androidx.datastore.SingleProcessDataStore.writeData$datastore_core_release(SingleProcessDataStore.kt:304)
at androidx.datastore.SingleProcessDataStore.transformAndWrite(SingleProcessDataStore.kt:282)
at androidx.datastore.SingleProcessDataStore$actor$1.invokeSuspend(SingleProcessDataStore.kt:165)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Any help would be appreciated.