Merge pull request #111 from zcash/101-improve-performance-api-25
[#101] Improve app startup pre API 26
This commit is contained in:
commit
8c514e8232
|
@ -2,6 +2,7 @@ package cash.z.ecc.ui
|
||||||
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
@ -10,7 +11,9 @@ import androidx.activity.viewModels
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import cash.z.ecc.sdk.model.PersistableWallet
|
import cash.z.ecc.sdk.model.PersistableWallet
|
||||||
import cash.z.ecc.ui.screen.backup.view.BackupWallet
|
import cash.z.ecc.ui.screen.backup.view.BackupWallet
|
||||||
import cash.z.ecc.ui.screen.backup.viewmodel.BackupViewModel
|
import cash.z.ecc.ui.screen.backup.viewmodel.BackupViewModel
|
||||||
|
@ -20,6 +23,10 @@ import cash.z.ecc.ui.screen.home.viewmodel.WalletViewModel
|
||||||
import cash.z.ecc.ui.screen.onboarding.view.Onboarding
|
import cash.z.ecc.ui.screen.onboarding.view.Onboarding
|
||||||
import cash.z.ecc.ui.screen.onboarding.viewmodel.OnboardingViewModel
|
import cash.z.ecc.ui.screen.onboarding.viewmodel.OnboardingViewModel
|
||||||
import cash.z.ecc.ui.theme.ZcashTheme
|
import cash.z.ecc.ui.theme.ZcashTheme
|
||||||
|
import cash.z.ecc.ui.util.AndroidApiVersion
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
@ -36,6 +43,37 @@ class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
setupSplashScreen()
|
setupSplashScreen()
|
||||||
|
|
||||||
|
if (AndroidApiVersion.isAtLeastO) {
|
||||||
|
setupUiContent()
|
||||||
|
} else {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
prefetchFontLegacy(applicationContext, R.font.rubik_medium)
|
||||||
|
prefetchFontLegacy(applicationContext, R.font.rubik_regular)
|
||||||
|
|
||||||
|
setupUiContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupSplashScreen() {
|
||||||
|
installSplashScreen().also {
|
||||||
|
val start = SystemClock.elapsedRealtime().milliseconds
|
||||||
|
it.setKeepVisibleCondition {
|
||||||
|
if (SPLASH_SCREEN_DELAY > Duration.ZERO) {
|
||||||
|
val now = SystemClock.elapsedRealtime().milliseconds
|
||||||
|
|
||||||
|
// This delay is for debug purposes only; do not enable for production usage.
|
||||||
|
if (now - start < SPLASH_SCREEN_DELAY) {
|
||||||
|
return@setKeepVisibleCondition true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletState.Loading == walletViewModel.state.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupUiContent() {
|
||||||
setContent {
|
setContent {
|
||||||
ZcashTheme {
|
ZcashTheme {
|
||||||
val walletState = walletViewModel.state.collectAsState().value
|
val walletState = walletViewModel.state.collectAsState().value
|
||||||
|
@ -59,24 +97,6 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSplashScreen() {
|
|
||||||
installSplashScreen().also {
|
|
||||||
val start = SystemClock.elapsedRealtime().milliseconds
|
|
||||||
it.setKeepVisibleCondition {
|
|
||||||
if (SPLASH_SCREEN_DELAY > Duration.ZERO) {
|
|
||||||
val now = SystemClock.elapsedRealtime().milliseconds
|
|
||||||
|
|
||||||
// This delay is for debug purposes only; do not enable for production usage.
|
|
||||||
if (now - start < SPLASH_SCREEN_DELAY) {
|
|
||||||
return@setKeepVisibleCondition true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WalletState.Loading == walletViewModel.state.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun WrapBackup(persistableWallet: PersistableWallet) {
|
private fun WrapBackup(persistableWallet: PersistableWallet) {
|
||||||
BackupWallet(
|
BackupWallet(
|
||||||
|
@ -115,3 +135,17 @@ class MainActivity : ComponentActivity() {
|
||||||
internal val SPLASH_SCREEN_DELAY = 0.seconds
|
internal val SPLASH_SCREEN_DELAY = 0.seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-fetches fonts on Android N (API 25) and below.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* ResourcesCompat is used implicitly by Compose on older Android versions.
|
||||||
|
* The backwards compatibility library performs disk IO and then
|
||||||
|
* caches the results. This moves that IO off the main thread, to prevent ANRs and
|
||||||
|
* jank during app startup.
|
||||||
|
*/
|
||||||
|
private suspend fun prefetchFontLegacy(context: Context, @androidx.annotation.FontRes fontRes: Int) =
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
ResourcesCompat.getFont(context, fontRes)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cash.z.ecc.ui.util
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.ChecksSdkIntAtLeast
|
||||||
|
import androidx.annotation.IntRange
|
||||||
|
|
||||||
|
object AndroidApiVersion {
|
||||||
|
/**
|
||||||
|
* @param sdk SDK version number to test against the current environment.
|
||||||
|
* @return `true` if [android.os.Build.VERSION.SDK_INT] is greater than or equal to
|
||||||
|
* [sdk].
|
||||||
|
*/
|
||||||
|
@ChecksSdkIntAtLeast(parameter = 0)
|
||||||
|
fun isAtLeast(@IntRange(from = Build.VERSION_CODES.BASE.toLong()) sdk: Int): Boolean {
|
||||||
|
return Build.VERSION.SDK_INT >= sdk
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.P)
|
||||||
|
val isAtLeastP = isAtLeast(Build.VERSION_CODES.P)
|
||||||
|
|
||||||
|
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O)
|
||||||
|
val isAtLeastO = isAtLeast(Build.VERSION_CODES.O)
|
||||||
|
|
||||||
|
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.Q)
|
||||||
|
val isAtLeastQ = isAtLeast(Build.VERSION_CODES.Q)
|
||||||
|
|
||||||
|
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R)
|
||||||
|
val isAtLeastR = isAtLeast(Build.VERSION_CODES.R)
|
||||||
|
|
||||||
|
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S)
|
||||||
|
val isAtLeastS = isAtLeast(Build.VERSION_CODES.S)
|
||||||
|
|
||||||
|
val isPreview = 0 != Build.VERSION.PREVIEW_SDK_INT
|
||||||
|
}
|
Loading…
Reference in New Issue