如果所有工作都在Main Threa執行會導致App的UI畫面卡頓、刷新頻率太低,影響使用者體驗。必須將這些跟UI沒有相關的工作,交給其他的執行緒處理,讓Main Thread專心處理UI的刷新,保持每隔16毫秒就可以更新一幀,也就是一秒可以刷60幀(遊戲常聽到的60fps)。
如果我們在Main Thread執行費時的工作或是API的請求,將會造成Main Thread被主塞,導致App被凍結。超過5秒,就會產生ANR(Application Not Responding)。
class LoginViewModel(){
fun login(){
//don't do this in prodcut code
task1 = thread {
respority.login(account, password, object: Callback<User> {
fun onSuccess(user: User) {
}
fun onFailure(exceptione: Exception) {
}
})
}
}
onCleared(){
task1.cancel()
}
}
class Respority {
fun login(account: String, password: String, result: Callback<User>) {
//do some connection
if(task is successful) {
result.onSuccess(user)
} else {
result.onFaliure(exception)
}
}
}
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
class LoginViewModel(){
fun login(){
viewModelScope.launch(Dispatchers.IO) {
val loginResult = login(account, password)
if (loginResult is Result.Success<User>) {
} else {
}
}
}
}
class Respority {
suspend fun login(account: String, password: String): Result<User> {
//do some connection
if(task is successful) {
return Result.Success(user)
} else {
return Result.Error(exception)
}
}
}
class LoginViewModel(){
fun login(){
//don't do this in prodcut code
task1 = thread {
respority.login(account, password, object: Callback<User> {
fun onSuccess(user: User) {
handleResult(user, object: Callback<String> {
fun onSuccess(token: String) {
// save token
}
fun onFailure(exceptione: Exception) {}
})
}
fun onFailure(exceptione: Exception) {
}
})
}
}
fun handleResult(user: User, callbak: Callback<String>) {
//do some compute
if(task is successful) {
callbak.onSuccess(token)
} else {
callbak.onFaliure(exception)
}
}
onCleared(){
task1.cancel()
}
}
class Respority {
fun login(account: String, password: String, callbak: Callback<User>) {
//do some connection
if(task is successful) {
callbak.onSuccess(user)
} else {
callbak.onFaliure(exception)
}
}
}
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
class LoginViewModel(){
fun login(){
viewModelScope.launch {
val user = withContext(Dispatchers.IO) {
login(account, password).getOrThrow()
}
val token = withContext(Dispatchers.Default) {
handleResult(user).getOrThrow()
}
// save token
}
}
suspend fun handleResult(user: User): Result<String> {
//do some compute
if(task is successful) {
return Result.Success(token)
} else {
return Result.Error(exception)
}
}
}
class Respority {
suspend fun login(account: String, password: String): Result<User> {
//do some connection
if(task is successful) {
return Result.Success(user)
} else {
return Result.Error(exception)
}
}
}