mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Warm up tzdata and cache DateTimeFormatters off the main thread
The first ZoneId.systemDefault() call lazily mmaps the tzdata file (ZoneInfoDb class init), which tripped StrictMode DiskReadViolation (~169 ms) on the main thread during LazyColumn composition in ApplicationsScreen. Mirror the Coil ImageLoader pre-warm: force the load on applicationIOScope in Amber.onCreate, and cache the two DateTimeFormatter instances instead of re-parsing the pattern per item.
This commit is contained in:
@@ -40,6 +40,7 @@ import com.greenart7c3.nostrsigner.database.LogDatabase
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.AmberSettings
|
||||
import com.greenart7c3.nostrsigner.models.FeedbackType
|
||||
import com.greenart7c3.nostrsigner.models.TimeUtils as AmberTimeUtils
|
||||
import com.greenart7c3.nostrsigner.models.TorMode
|
||||
import com.greenart7c3.nostrsigner.models.UpdateCheckFrequency
|
||||
import com.greenart7c3.nostrsigner.okhttp.HttpClientManager
|
||||
@@ -354,6 +355,13 @@ class Amber :
|
||||
applicationIOScope.launch {
|
||||
SingletonImageLoader.get(this@Amber)
|
||||
}
|
||||
|
||||
// The first ZoneId.systemDefault() call lazily mmaps tzdata from disk.
|
||||
// Force it here so it never happens on the main thread during the first
|
||||
// timestamp formatted in composition (StrictMode DiskReadViolation).
|
||||
applicationIOScope.launch {
|
||||
AmberTimeUtils.warmUp()
|
||||
}
|
||||
}
|
||||
|
||||
private fun enableStrictMode() {
|
||||
|
||||
@@ -6,15 +6,29 @@ import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object TimeUtils {
|
||||
// DateTimeFormatter is immutable and thread-safe; building it parses the
|
||||
// pattern on every call, so cache the two instances used during composition.
|
||||
private val formatter = DateTimeFormatter.ofPattern("HH:mm - dd MMM")
|
||||
private val formatterWithSeconds = DateTimeFormatter.ofPattern("HH:mm:ss - dd MMM")
|
||||
|
||||
/**
|
||||
* The first ZoneId.systemDefault() call in the process lazily loads the
|
||||
* tzdata file from disk (ZoneInfoDb's class initializer). Calling this from
|
||||
* a background thread at app start keeps that disk read off the main
|
||||
* thread, where it would otherwise trip StrictMode and jank the frame that
|
||||
* first formats a timestamp.
|
||||
*/
|
||||
fun warmUp() {
|
||||
LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault()).format(formatter)
|
||||
}
|
||||
|
||||
fun formatLongToCustomDateTime(longValue: Long): String {
|
||||
val dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault())
|
||||
val formatter = DateTimeFormatter.ofPattern("HH:mm - dd MMM")
|
||||
return dateTime.format(formatter)
|
||||
}
|
||||
|
||||
fun formatLongToCustomDateTimeWithSeconds(longValue: Long): String {
|
||||
val dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault())
|
||||
val formatter = DateTimeFormatter.ofPattern("HH:mm:ss - dd MMM")
|
||||
return dateTime.format(formatter)
|
||||
return dateTime.format(formatterWithSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user