目录
- 网络权限配置 - 在
AndroidManifest.xml中声明权限 - 网络连接检查 - 确保设备已连接到网络
- 核心网络请求方式
- 传统方式:
HttpURLConnection(已过时,但作为基础了解) - 现代推荐方式:
Retrofit+OkHttp+Gson(黄金组合)
- 传统方式:
- 处理异步任务与线程 - 避免在主线程进行网络请求
- 解析服务器返回的数据 - 从 JSON 到 Kotlin/Java 对象
- 展示数据 - 使用
RecyclerView和Adapter - 完整项目示例
- 高级主题与最佳实践
网络权限配置
你的应用必须声明它有访问互联网的权限,在 在发起网络请求前,最好检查一下设备是否已连接到网络,这可以通过 在 Android 10 (API 29) 及以上版本,需要请求 这是 Android SDK 自带的、最底层的 API,它功能简单,但需要手动处理很多细节(如线程、JSON 解析),不推荐在新项目中使用。 这是目前 Android 开发中最流行、最强大的网络请求解决方案。 步骤 1: 添加依赖 在 步骤 2: 创建数据类 根据 API 返回的 JSON 结构创建对应的 Kotlin 数据类。 步骤 3: 定义 Retrofit API 接口 创建一个接口,用注解来描述 API 请求。 步骤 4: 创建 Retrofit 实例 绝对不能在主线程(UI线程)中进行网络请求! 否则会抛出 现代 Android 开发推荐使用 Kotlin 协程 来处理异步任务,它比传统的 在 这个例子将展示如何使用 步骤 1: 布局文件 步骤 2: RecyclerView Item 布局 app/src/main/AndroidManifest.xml 文件中添加以下 <uses-permission>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 访问互联网的权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许应用在后台运行时使用网络(可选,根据需求) -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
...>
...
</application>
</manifest>
网络连接检查
ConnectivityManager 来实现。
ACCESS_NETWORK_STATE 权限。import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.os.Build
object NetworkUtils {
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val activeNetwork = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
return when {
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
} else {
@Suppress("DEPRECATION")
val networkInfo = connectivityManager.activeNetworkInfo ?: return false
@Suppress("DEPRECATION")
return networkInfo.isConnected
}
}
}
核心网络请求方式
HttpURLConnection (已过时)
// 在一个后台线程中执行
Thread(Runnable {
val url = URL("https://api.example.com/data")
val urlConnection = url.openConnection() as HttpURLConnection
try {
val `in` = urlConnection.inputStream
// 读取输入流 `in` 的内容
val response = readStream(`in`)
Log.d("Response", response)
} finally {
urlConnection.disconnect()
}
}).start()
Retrofit + OkHttp + Gson (强烈推荐)

app/build.gradle.kts (或 app/build.gradle) 文件中添加:// build.gradle.kts
dependencies {
// Retrofit & OkHttp
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") // JSON 转换器
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0") // OkHttp 日志拦截器
// ViewModel & LiveData (用于UI更新)
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.activity:activity-ktx:1.8.0") // by viewModels
}
data class Todo(
val userId: Int,
val id: Int,
val title: String,
val completed: Boolean
)
// 假设 API 返回一个列表: [ { ... }, { ... } ]
typealias TodoList = List<Todo>
import retrofit2.http.GET
import retrofit2.http.Path
interface TodoApiService {
// GET https://jsonplaceholder.typicode.com/todos/1
@GET("todos/{id}")
suspend fun getTodo(@Path("id") todoId: Int): Todo
// GET https://jsonplaceholder.typicode.com/todos
@GET("todos")
suspend fun getTodos(): TodoList
}
suspend 关键字表示这个函数可以在协程中挂起执行,非常适合处理网络这种耗时操作。import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
private const val BASE_URL = "https://jsonplaceholder.typicode.com/"
val instance: TodoApiService by lazy {
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
retrofit.create(TodoApiService::class.java)
}
}
处理异步任务与线程
NetworkOnMainThreadException 异常并导致应用卡顿。AsyncTask 或回调更简洁、更强大。ViewModel 中使用协程是最佳实践,因为它能很好地配合 LifecycleOwner (如 Activity 或 Fragment) 来管理协程的生命周期,避免内存泄漏。
完整项目示例:获取并展示 Todo 列表
ViewModel、LiveData、RecyclerView 和 Retrofit 从网络获取数据并展示在界面上。activity_main.xml<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/item_todo" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_todo.xml
<?xml version="
