第12天:后台任务-补充材料——MainActivity.kt‘解读

下面是对“第12天:后台任务”该文学习的更深层次的补充材料,对 '‘MainActivity.kt’ 文件的理解。这将帮助您深入理解每一行代码的作用,以及它们在整个项目中的意义。
这段代码是一个Android应用程序,使用协程从网络获取数据并显示在界面上。它使用了lifecycleScope来管理协程的生命周期,并在后台线程中执行网络请求。下面是对代码逐句的详细解释:

包和导入

package com.example.backgroundtaskdemo
  • 这是定义类所在的包名,表示MainActivity类属于com.example.backgroundtaskdemo包。
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import androidx.lifecycle.lifecycleScope
  • import语句:导入了所需的类和库。
    • AppCompatActivity:是所有Android活动(Activity)的基类,提供了向后兼容的特性。
    • Bundle:用于保存活动的状态。
    • ButtonTextView:用于用户界面的按钮和文本视图控件。
    • kotlinx.coroutines.*:导入Kotlin协程库,用于处理异步任务。
    • HttpURLConnectionURL:用于网络请求。
    • lifecycleScope:绑定到Activity的生命周期,确保协程在Activity销毁时自动取消。

MainActivity

class MainActivity : AppCompatActivity() {
  • 定义了MainActivity类,它继承自AppCompatActivity,表示这是一个活动类,负责处理与用户的交互。

成员变量

private lateinit var btnFetch: Button
private lateinit var tvResult: TextView
  • btnFetchtvResult:声明两个控件变量,分别用于按钮和显示结果的文本框。
  • lateinit:用于延迟初始化变量,确保它们在使用前已经赋值。

onCreate() 方法

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
  • onCreate():这是Activity的生命周期方法,当Activity第一次创建时调用。
  • setContentView(R.layout.activity_main):设置Activity的布局,使用的是activity_main.xml中的UI设计。

视图初始化

btnFetch = findViewById(R.id.btn_fetch)
tvResult = findViewById(R.id.tv_result)
  • findViewById():从布局中获取按钮和文本视图控件,分别赋值给btnFetchtvResult变量。

按钮点击事件

btnFetch.setOnClickListener {
    fetchData()
}
  • btnFetch按钮设置点击监听器,当用户点击按钮时,会调用fetchData()方法去执行网络请求。

fetchData() 方法

private fun fetchData() {
    lifecycleScope.launch {
        tvResult.text = "正在下载数据..."
        try {
            val data = withContext(Dispatchers.IO) {
                downloadData("https://api.github.com/")
            }
            tvResult.text = data
        } catch (e: Exception) {
            tvResult.text = "发生错误: ${e.message}"
        }
    }
}
  • lifecycleScope.launch:启动一个协程,协程的生命周期由lifecycleScope管理,确保协程会在Activity销毁时自动取消,避免内存泄漏。

  • tvResult.text = "正在下载数据...":在执行网络请求前,更新UI,显示提示信息“正在下载数据…”。

  • withContext(Dispatchers.IO):指定在IO调度器中执行网络请求。Dispatchers.IO是一个为I/O操作(如网络、文件读取等)优化的线程池。

  • downloadData("https://api.github.com/"):调用downloadData()方法执行网络请求。

  • tvResult.text = data:成功获取数据后,更新tvResult文本框内容为获取到的数据。

  • catch (e: Exception):捕获异常,如果请求失败,将错误信息显示在tvResult中。

downloadData() 挂起函数

private suspend fun downloadData(urlString: String): String {
    return withContext(Dispatchers.IO) {
        val url = URL(urlString)
        val connection = url.openConnection() as HttpURLConnection
        try {
            connection.requestMethod = "GET"
            connection.connectTimeout = 5000
            connection.readTimeout = 5000

            val responseCode = connection.responseCode
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw Exception("HTTP错误代码: $responseCode")
            }

            val stream = connection.inputStream
            val reader = BufferedReader(InputStreamReader(stream))
            val response = StringBuilder()
            var line: String?

            while (reader.readLine().also { line = it } != null) {
                response.append(line)
            }

            reader.close()
            response.toString()
        } finally {
            connection.disconnect()
        }
    }
}
  • suspend:标记这是一个挂起函数,意味着它可以在协程中被挂起和恢复,用于执行耗时操作。
  • withContext(Dispatchers.IO):再次指定使用IO调度器执行I/O操作,确保网络请求在后台线程中运行。
  • HttpURLConnection:用于发起HTTP请求,这里使用的是GET请求方法,设置了连接和读取超时时间为5000毫秒(5秒)。
  • responseCode:获取响应码,如果不是HTTP_OK(即状态码200),则抛出异常。
  • BufferedReader:读取输入流中的响应数据,将其逐行读取并拼接成字符串。
  • finally:无论网络请求是否成功,最后都会调用connection.disconnect()来关闭连接。

总结

  • 这段代码展示了如何在Android应用中使用协程来执行网络请求,并确保UI更新发生在主线程中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值