Skip to content
This repository was archived by the owner on Jul 18, 2024. It is now read-only.

Commit

Permalink
app: Optimize coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
YuKongA committed May 4, 2024
1 parent 5cfbc73 commit 1f42170
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 130 deletions.
144 changes: 70 additions & 74 deletions app/src/main/kotlin/top/yukonga/update/activity/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.google.android.material.checkbox.MaterialCheckBox
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.MaterialAutoCompleteTextView
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -105,36 +105,39 @@ class MainActivity : AppCompatActivity() {

// Setup Fab OnClickListener.
activityMainBinding.implement.setOnClickListener {

hapticConfirm(activityMainBinding.implement)

CoroutineScope(Dispatchers.Default).launch {

try {
val deviceRegion = deviceRegion.editText?.text.toString()
val codeName = codeName.editText?.text.toString()
val deviceName = deviceName.editText?.text.toString()
val deviceRegion = deviceRegion.editText?.text.toString()
val codeName = codeName.editText?.text.toString()
val deviceName = deviceName.editText?.text.toString()

val regionCode = DeviceInfoHelper.regionCode(deviceRegion)
val regionNameExt = DeviceInfoHelper.regionNameExt(deviceRegion)
val codeNameExt = codeName + regionNameExt
val regionCode = DeviceInfoHelper.regionCode(deviceRegion)
val regionNameExt = DeviceInfoHelper.regionNameExt(deviceRegion)
val codeNameExt = codeName + regionNameExt

val androidVersion = androidVersion.editText?.text.toString()
val systemVersion = systemVersion.editText?.text.toString()
val androidVersion = androidVersion.editText?.text.toString()
val systemVersion = systemVersion.editText?.text.toString()

val deviceCode = DeviceInfoHelper.deviceCode(androidVersion, codeName, regionCode)
val systemVersionTextExt = systemVersion.replace("OS1", "V816").replace("AUTO", deviceCode)
val deviceCode = DeviceInfoHelper.deviceCode(androidVersion, codeName, regionCode)
val systemVersionTextExt = systemVersion.replace("OS1", "V816").replace("AUTO", deviceCode)

// Acquire ROM info.
// Acquire ROM info.
lifecycleScope.launch(Dispatchers.IO) {
try {
val recoveryRomInfo = json.decodeFromString<RomInfoHelper.RomInfo>(
getRecoveryRomInfo(
this@MainActivity, codeNameExt, regionCode, systemVersionTextExt, androidVersion
this@MainActivity,
codeNameExt,
regionCode,
systemVersionTextExt,
androidVersion
)
)
prefs.edit().putString("deviceName", deviceName).putString("codeName", codeName).putString("deviceRegion", deviceRegion)
.putString("systemVersion", systemVersion).putString("androidVersion", androidVersion).apply()

withContext(Dispatchers.Main) {
prefs.edit().putString("deviceName", deviceName).putString("codeName", codeName).putString("deviceRegion", deviceRegion)
.putString("systemVersion", systemVersion).putString("androidVersion", androidVersion).apply()

// Hide all cardViews & Show a toast if we didn't get anything from request.
if (recoveryRomInfo.currentRom?.branch == null) {
Expand Down Expand Up @@ -228,12 +231,13 @@ class MainActivity : AppCompatActivity() {
}
setupCardViews()

} // Main context
} // Dispatchers.Main

} catch (e: Exception) {
e.printStackTrace()
}

} // CoroutineScope
} // Coroutine

} // Fab operation

Expand Down Expand Up @@ -310,10 +314,10 @@ class MainActivity : AppCompatActivity() {
val savePassword = prefs.getString("save_password", "") ?: "0"
val mInputAccount = inputAccount.text.toString()
val mInputPassword = inputPassword.text.toString()
CoroutineScope(Dispatchers.Default).launch {
lifecycleScope.launch(Dispatchers.IO) {
val isValid = LoginUtils().login(this@MainActivity, mInputAccount, mInputPassword, global, savePassword)
if (isValid) {
withContext(Dispatchers.Main) {
withContext(Dispatchers.Main) {
if (isValid) {
mainContentBinding.apply {
loginIcon.setImageResource(R.drawable.ic_check_circle)
loginTitle.text = getString(R.string.logged_in)
Expand All @@ -339,19 +343,15 @@ class MainActivity : AppCompatActivity() {
}
setPositiveButton(getString(R.string.confirm)) { _, _ ->
hapticConfirm(activityMainBinding.toolbar)
CoroutineScope(Dispatchers.Default).launch {
LoginUtils().logout(this@MainActivity)
withContext(Dispatchers.Main) {
mainContentBinding.apply {
loginIcon.setImageResource(R.drawable.ic_cancel)
loginTitle.text = getString(R.string.no_account)
loginDesc.text = getString(R.string.login_desc)
}
activityMainBinding.apply {
toolbar.menu.findItem(R.id.login).isVisible = true
toolbar.menu.findItem(R.id.logout).isVisible = false
}
}
LoginUtils().logout(this@MainActivity)
mainContentBinding.apply {
loginIcon.setImageResource(R.drawable.ic_cancel)
loginTitle.text = getString(R.string.no_account)
loginDesc.text = getString(R.string.login_desc)
}
activityMainBinding.apply {
toolbar.menu.findItem(R.id.login).isVisible = true
toolbar.menu.findItem(R.id.logout).isVisible = false
}
}
}.show()
Expand Down Expand Up @@ -483,44 +483,40 @@ class MainActivity : AppCompatActivity() {
val firstViewArray = arrayOf(firstInfo, secondInfo)
val secondViewArray = arrayOf(secondInfo, downloadInfo, bigVersion, bigVersionInfo)

CoroutineScope(Dispatchers.Default).launch {
withContext(Dispatchers.Main) {
if (mainViewModel.device != null) {
firstViewArray.forEach {
if (!it.isVisible) it.fadInAnimation()
}
activityMainBinding.implement.shrink()
codenameInfo.setTextAnimation(mainViewModel.device)
systemInfo.setTextAnimation(mainViewModel.version)
codebaseInfo.setTextAnimation(mainViewModel.codebase)
branchInfo.setTextAnimation(mainViewModel.branch)
} else {
activityMainBinding.implement.extend()
firstViewArray.forEach {
if (it.isVisible) it.fadOutAnimation()
}
}
if (mainViewModel.filename != null) {
secondViewArray.forEach {
if (!it.isVisible) it.fadInAnimation()
}
bigVersionInfo.setTextAnimation(mainViewModel.bigversion)
filenameInfo.setTextAnimation(mainViewModel.filename)
filesizeInfo.setTextAnimation(mainViewModel.filesize)
changelogInfo.setTextAnimation(mainViewModel.changelog)
changelogInfo.setCopyClickListener(this@MainActivity, mainViewModel.changelog)
official.text = mainViewModel.officialText
officialDownload.setDownloadClickListener(this@MainActivity, mainViewModel.filename, mainViewModel.officialDownload!!)
officialCopy.setCopyClickListener(this@MainActivity, mainViewModel.officialDownload)
cdn1Download.setDownloadClickListener(this@MainActivity, mainViewModel.filename, mainViewModel.cdn1Download!!)
cdn1Copy.setCopyClickListener(this@MainActivity, mainViewModel.cdn1Download)
cdn2Download.setDownloadClickListener(this@MainActivity, mainViewModel.filename, mainViewModel.cdn2Download!!)
cdn2Copy.setCopyClickListener(this@MainActivity, mainViewModel.cdn2Download)
} else {
secondViewArray.forEach {
if (it.isVisible) it.fadOutAnimation()
}
}
if (mainViewModel.device != null) {
firstViewArray.forEach {
if (!it.isVisible) it.fadInAnimation()
}
activityMainBinding.implement.shrink()
codenameInfo.setTextAnimation(mainViewModel.device)
systemInfo.setTextAnimation(mainViewModel.version)
codebaseInfo.setTextAnimation(mainViewModel.codebase)
branchInfo.setTextAnimation(mainViewModel.branch)
} else {
activityMainBinding.implement.extend()
firstViewArray.forEach {
if (it.isVisible) it.fadOutAnimation()
}
}
if (mainViewModel.filename != null) {
secondViewArray.forEach {
if (!it.isVisible) it.fadInAnimation()
}
bigVersionInfo.setTextAnimation(mainViewModel.bigversion)
filenameInfo.setTextAnimation(mainViewModel.filename)
filesizeInfo.setTextAnimation(mainViewModel.filesize)
changelogInfo.setTextAnimation(mainViewModel.changelog)
changelogInfo.setCopyClickListener(this@MainActivity, mainViewModel.changelog)
official.text = mainViewModel.officialText
officialDownload.setDownloadClickListener(this@MainActivity, mainViewModel.filename, mainViewModel.officialDownload!!)
officialCopy.setCopyClickListener(this@MainActivity, mainViewModel.officialDownload)
cdn1Download.setDownloadClickListener(this@MainActivity, mainViewModel.filename, mainViewModel.cdn1Download!!)
cdn1Copy.setCopyClickListener(this@MainActivity, mainViewModel.cdn1Download)
cdn2Download.setDownloadClickListener(this@MainActivity, mainViewModel.filename, mainViewModel.cdn2Download!!)
cdn2Copy.setCopyClickListener(this@MainActivity, mainViewModel.cdn2Download)
} else {
secondViewArray.forEach {
if (it.isVisible) it.fadOutAnimation()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ object InfoUtils {
}

fun getRecoveryRomInfo(context: Context, codeNameExt: String, regionCode: String, romVersion: String, androidVersion: String): String {

if (FileUtils.isCookiesFileExists(context)) {
val cookiesFile = FileUtils.readCookiesFile(context)
val cookies = json.decodeFromString<LoginHelper>(cookiesFile)
Expand Down
36 changes: 10 additions & 26 deletions app/src/main/kotlin/top/yukonga/update/logic/utils/LoginUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,24 @@ class LoginUtils {
private val loginAuth2Url = "https://account.xiaomi.com/pass/serviceLoginAuth2"
private val mediaType = "application/x-www-form-urlencoded".toMediaType()

suspend fun login(context: Context, account: String, password: String, global: String, savePassword: String, autoLogin: Boolean = false): Boolean {
fun login(context: Context, account: String, password: String, global: String, savePassword: String, autoLogin: Boolean = false): Boolean {
if (account.isEmpty() || password.isEmpty()) {
withContext(Dispatchers.Main) {
showStringToast(context, context.getString(R.string.account_or_password_empty), 0)
}
showStringToast(context, context.getString(R.string.account_or_password_empty), 0)
return false
} else {
withContext(Dispatchers.Main) {
if (!autoLogin) showStringToast(context, context.getString(R.string.logging_in), 1)
}
if (!autoLogin) showStringToast(context, context.getString(R.string.logging_in), 1)
}

if (savePassword == "1") saveAccountAndPassword(context, account, password) else deleteAccountAndPassword(context)


val md = MessageDigest.getInstance("MD5")
md.update(password.toByteArray())
val passwordHash = md.digest().joinToString("") { "%02x".format(it) }.uppercase()

val response1 = getRequest(loginUrl)
val sign = response1.request.url.queryParameter("_sign")?.replace("2&V1_passport&", "")
if (sign == null) {
withContext(Dispatchers.Main) {
showStringToast(context, context.getString(R.string.request_sign_failed), 0)
}
showStringToast(context, context.getString(R.string.request_sign_failed), 0)
return false
}

Expand All @@ -71,17 +64,13 @@ class LoginUtils {
val authResult = if (authJson.result == "ok") "1" else "0"

if (description != "成功") {
withContext(Dispatchers.Main) {
if (description == "登录验证失败") showStringToast(context, context.getString(R.string.login_error), 0)
else showStringToast(context, description, 0)
}
if (description == "登录验证失败") showStringToast(context, context.getString(R.string.login_error), 0)
else showStringToast(context, description, 0)
return false
}

if (nonce == null || ssecurity == null || location == null || userId.isEmpty()) {
withContext(Dispatchers.Main) {
showStringToast(context, context.getString(R.string.security_error), 0)
}
showStringToast(context, context.getString(R.string.security_error), 0)
return false
}

Expand All @@ -95,19 +84,14 @@ class LoginUtils {
val serviceToken = cookies.split("serviceToken=")[1].split(";")[0]

val loginInfo = LoginHelper(accountType, authResult, description, ssecurity, serviceToken, userId)

withContext(Dispatchers.Main) {
saveCookiesFile(context, Json.encodeToString(loginInfo))
showStringToast(context, context.getString(R.string.login_successful), 1)
}
saveCookiesFile(context, Json.encodeToString(loginInfo))
showStringToast(context, context.getString(R.string.login_successful), 1)
return true
}

suspend fun logout(context: Context) {
withContext(Dispatchers.Main) {
fun logout(context: Context) {
deleteCookiesFile(context)
showStringToast(context, context.getString(R.string.logout_successful), 1)
}
}

private fun saveAccountAndPassword(context: Context, account: String, password: String) {
Expand Down
39 changes: 10 additions & 29 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 -XX:+UseParallelGC
org.gradle.caching=true
org.gradle.parallel=true

android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
# Only keep the single relevant constructor for types mentioned in XML files
# instead of using a parameter wildcard which keeps them all
android.useMinimalKeepRules=true
# Enable resource optimizations for release build
android.injected.testOnly=false
android.includeDependencyInfoInApks=false
android.enableResourceOptimizations=true
# Gradle
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.caching=true

# Kotlin
kotlin.code.style=official
kotlin.daemon.useFallbackStrategy=false

0 comments on commit 1f42170

Please sign in to comment.