贝博恩创新科技网

android api连互联网

目录

  1. 网络权限配置 - 在 AndroidManifest.xml 中声明权限
  2. 网络连接检查 - 确保设备已连接到网络
  3. 核心网络请求方式
    • 传统方式: HttpURLConnection (已过时,但作为基础了解)
    • 现代推荐方式: Retrofit + OkHttp + Gson (黄金组合)
  4. 处理异步任务与线程 - 避免在主线程进行网络请求
  5. 解析服务器返回的数据 - 从 JSON 到 Kotlin/Java 对象
  6. 展示数据 - 使用 RecyclerViewAdapter
  7. 完整项目示例
  8. 高级主题与最佳实践

网络权限配置

你的应用必须声明它有访问互联网的权限,在 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 来实现。

android api连互联网-图1
(图片来源网络,侵删)

在 Android 10 (API 29) 及以上版本,需要请求 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 (已过时)

这是 Android SDK 自带的、最底层的 API,它功能简单,但需要手动处理很多细节(如线程、JSON 解析),不推荐在新项目中使用。

// 在一个后台线程中执行
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 (强烈推荐)

这是目前 Android 开发中最流行、最强大的网络请求解决方案。

  • Retrofit: 一个类型安全的 HTTP 客户端,它将 REST API 的端点(URL)转换为 Java/Kotlin 接口,让你可以用面向对象的方式调用网络请求。
  • OkHttp: 一个高效的 HTTP 客户端,负责处理底层的网络连接、缓存、超时等,Retrofit 内部默认使用 OkHttp。
  • Gson (或其他如 Moshi, Jackson): 用于将 JSON 数据自动解析为 Kotlin/Java 对象,或将对象序列化为 JSON。

步骤 1: 添加依赖

android api连互联网-图2
(图片来源网络,侵删)

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
}

步骤 2: 创建数据类

根据 API 返回的 JSON 结构创建对应的 Kotlin 数据类。

data class Todo(
    val userId: Int,
    val id: Int,
    val title: String,
    val completed: Boolean
)
// 假设 API 返回一个列表: [ { ... }, { ... } ]
typealias TodoList = List<Todo>

步骤 3: 定义 Retrofit API 接口

android api连互联网-图3
(图片来源网络,侵删)

创建一个接口,用注解来描述 API 请求。

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 关键字表示这个函数可以在协程中挂起执行,非常适合处理网络这种耗时操作。

步骤 4: 创建 Retrofit 实例

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)
    }
}

处理异步任务与线程

绝对不能在主线程(UI线程)中进行网络请求! 否则会抛出 NetworkOnMainThreadException 异常并导致应用卡顿。

现代 Android 开发推荐使用 Kotlin 协程 来处理异步任务,它比传统的 AsyncTask 或回调更简洁、更强大。

ViewModel 中使用协程是最佳实践,因为它能很好地配合 LifecycleOwner (如 ActivityFragment) 来管理协程的生命周期,避免内存泄漏。


完整项目示例:获取并展示 Todo 列表

这个例子将展示如何使用 ViewModelLiveDataRecyclerView 和 Retrofit 从网络获取数据并展示在界面上。

步骤 1: 布局文件 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>

步骤 2: RecyclerView Item 布局 item_todo.xml

<?xml version="
分享:
扫描分享到社交APP
上一篇
下一篇