12.1Android中协程的基本使用
- 游戏开发
- 2025-08-28 10:39:01

文章目录 前言1、导入依赖2、使用协程获取服务器中的数据2.1 定义请求回调结果的数据类2.2 网络请求 3、网络回调结构4、通过ViewModel处理网络请求数据 前言
在使用协程的时候一直没有一个具体的概念,只知道协程能够使得异步操作等同于同步操作,且不会造成线程阻塞,且第一次使用协程是根据前辈的代码修改而学会的,没有一个规范性的思维,通过查看官方资料将协程的使用重新梳理一遍,一个简单,不麻烦的做法。
1、导入依赖选择依赖的方式主要分为两种,查看创建项目的时候中Build configuration language的选项选择的某一项,根据项目来选择
Groovy:
dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' }kotlin:
dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9") } 2、使用协程获取服务器中的数据目的: 防止直接在UI线程中进行网络请求出现线程阻塞,导致应用程序无响应(ANR)
Dispatchers.IO: 用于执行I/O操作,如读写文件、访问数据库等。 这个调度器会尝试在后台线程池中执行I/O密集型任务,从而避免阻塞主线程。
Dispatchers.Main: 用于在Android的主线程(UI线程)上执行协程。 这个调度器确保与UI相关的操作(如更新UI元素)在主线程上执行。 在非Android平台上(如桌面应用或纯Kotlin项目),Dispatchers.Main 可能不可用或行为不同。
Dispatchers.Default: 用于执行计算密集型任务。可用于执行网络请求,获取服务器数据 这个调度器使用共享的后台线程池来执行协程,从而优化CPU资源的利用。 它是默认的调度器,如果你没有为协程指定调度器,那么它将使用 Dispatchers.Default。
Dispatchers.Unconfined: 不绑定到任何特定的线程。 协程在哪个线程上启动,它就会在那个线程上继续执行,直到遇到挂起点(如 suspend 函数调用)。 一旦协程挂起并恢复,它可能会在任何线程上继续执行,这取决于挂起函数的实现。
通常不建议在生产代码中使用 Dispatchers.Unconfined,因为它可能导致难以追踪的线程安全问题。 用法:
// 创建一个协程作用域(通常是在ViewModel、Activity或Fragment中) val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) // 在协程作用域中启动一个协程 coroutineScope.launch(Dispatchers.IO) { // 执行I/O操作 } 2.1 定义请求回调结果的数据类sealed 关键字 sealed 关键字用于定义一个密封类(sealed class),用于控制子类的个数,只接受子类在密封类的同一个文件中声明,或者作为密封类的嵌套类。
有助于改进when表达式,当使用密封类的时候,编译器会确保when表达式覆盖所有可能得子类,如果没有覆盖的话,则会出现报错的提醒,这有助于提高代码的健壮性和可维护性。
sealed class Result<out R> { data class Success<out T>(val data: T) : Result<T>() data class Error(val exception: Exception) : Result<Nothing>() } 2.2 网络请求为了防止主线程调用 makeLoginRequest 后出现阻塞界面情况。可以使用协程库中的 withContext() 函数将协程的执行操作移至其他线程,在其中执行耗时的网络请求操作
class LoginRepository(private val responseParser: LoginResponseParser) { private const val loginUrl = " example /login" suspend fun makeLoginRequest( jsonBody: String ): Result<LoginResponse> { return withContext(Dispatchers.IO) { // Blocking network request code val url = URL(loginUrl) (url.openConnection() as? HttpURLConnection)?.run { requestMethod = "POST" setRequestProperty("Content-Type", "application/json; utf-8") setRequestProperty("Accept", "application/json") doOutput = true outputStream.write(jsonBody.toByteArray()) return Result.Success(responseParser.parse(inputStream)) } return Result.Error(Exception("Cannot open HttpURLConnection")) } } } 3、网络回调结构假设请求回调的结构为:
{ "success": true, "user": { "id": 123, "username": "exampleUser", "email": "example@example " }, "token": "some_jwt_token" }为了适配并处理网络请求回调的数据,需要创建数据类,方便适配回调数据。
data class User( val id: Int, val username: String, val email: String ) data class LoginResponse( val success: Boolean, val user: User?, val token: String? )将网络请求返回的InoutStream通过LoginResponseParser 处理,读取返回的数据并进行处理,转为LoginResponse的数据。
import com.google.gson.Gson import com.google.gson.JsonSyntaxException import java.io.BufferedReader import java.io.InputStream import java.io.InputStreamReader object LoginResponseParser { private val gson = Gson() @Throws(JsonSyntaxException::class) fun parse(inputStream: InputStream): LoginResponse { return try { // 使用try-with-resources语句自动关闭BufferedReader gson.fromJson( BufferedReader(InputStreamReader(inputStream)).use {it.readText()} , LoginResponse::class.java) } catch (e: IOException) { // 处理IOException,例如记录日志或抛出运行时异常 throw RuntimeException("Failed to read input stream", e) } catch (e: JsonSyntaxException) { // 处理JsonSyntaxException,例如记录日志或抛出运行时异常 throw RuntimeException("Failed to parse JSON", e) } } } 4、通过ViewModel处理网络请求数据 class LoginViewModel( private val loginRepository: LoginRepository ): ViewModel() { fun login(username: String, token: String) { viewModelScope.launch { val jsonBody = "{ username: \"$username\", token: \"$token\"}" val result = try { loginRepository.makeLoginRequest(jsonBody) } catch(e: Exception) { Result.Error(Exception("Network request failed")) } when (result) { is Result.Success<LoginResponse> -> // Happy path else -> Result.Error(Exception("reponse is error"))// Show error in UI } } } }想要了解更多协程相关的知识点,可以查看官网
12.1Android中协程的基本使用由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“12.1Android中协程的基本使用”