Android网络编程基础 #
一、网络权限 #
1.1 添加网络权限 #
xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- 网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 网络状态权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- WiFi状态权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>
1.2 检查网络状态 #
kotlin
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
} else {
val networkInfo = connectivityManager.activeNetworkInfo
return networkInfo?.isConnected == true
}
}
fun isWifiConnected(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
} else {
val networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
return networkInfo?.isConnected == true
}
}
二、HTTP协议 #
2.1 HTTP请求方法 #
| 方法 | 说明 |
|---|---|
| GET | 获取资源 |
| POST | 提交数据 |
| PUT | 更新资源 |
| DELETE | 删除资源 |
| PATCH | 部分更新 |
| HEAD | 获取响应头 |
2.2 HTTP状态码 #
| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 201 | 创建成功 |
| 204 | 无内容 |
| 301 | 永久重定向 |
| 302 | 临时重定向 |
| 400 | 请求错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器错误 |
| 502 | 网关错误 |
| 503 | 服务不可用 |
2.3 HTTP请求头 #
kotlin
val headers = mapOf(
"Content-Type" to "application/json",
"Accept" to "application/json",
"Authorization" to "Bearer token",
"User-Agent" to "MyApp/1.0",
"Cache-Control" to "no-cache"
)
三、网络安全配置 #
3.1 创建网络安全配置文件 #
xml
<!-- res/xml/network_security_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!-- 允许明文传输(仅用于开发环境) -->
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<!-- 限制特定域名 -->
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">example.com</domain>
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</domain-config>
<!-- 自定义证书 -->
<domain-config>
<domain includeSubdomains="true">secure.example.com</domain>
<trust-anchors>
<certificates src="@raw/my_cert" />
</trust-anchors>
</domain-config>
</network-security-config>
3.2 在AndroidManifest中引用 #
xml
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
</application>
3.3 Android 9+ 明文传输 #
Android 9及以上默认禁止明文HTTP请求,需要配置:
xml
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
四、使用HttpURLConnection #
4.1 GET请求 #
kotlin
fun httpGet(urlString: String): String {
var connection: HttpURLConnection? = null
try {
val url = URL(urlString)
connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.connectTimeout = 10000
connection.readTimeout = 10000
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
return connection.inputStream.bufferedReader().readText()
} else {
throw Exception("HTTP Error: $responseCode")
}
} finally {
connection?.disconnect()
}
}
4.2 POST请求 #
kotlin
fun httpPost(urlString: String, jsonBody: String): String {
var connection: HttpURLConnection? = null
try {
val url = URL(urlString)
connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.connectTimeout = 10000
connection.readTimeout = 10000
connection.doOutput = true
connection.setRequestProperty("Content-Type", "application/json")
connection.outputStream.use { output ->
output.write(jsonBody.toByteArray())
}
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
return connection.inputStream.bufferedReader().readText()
} else {
throw Exception("HTTP Error: $responseCode")
}
} finally {
connection?.disconnect()
}
}
4.3 在协程中使用 #
kotlin
class NetworkRepository {
suspend fun fetchData(url: String): String = withContext(Dispatchers.IO) {
httpGet(url)
}
suspend fun postData(url: String, body: String): String = withContext(Dispatchers.IO) {
httpPost(url, body)
}
}
五、网络监听 #
5.1 注册网络回调 #
kotlin
class NetworkCallback : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("Network", "网络可用")
}
override fun onLost(network: Network) {
Log.d("Network", "网络丢失")
}
override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
val isWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
val isCellular = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
Log.d("Network", "WiFi: $isWifi, Cellular: $isCellular")
}
}
// 注册
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, NetworkCallback())
// 注销
connectivityManager.unregisterNetworkCallback(networkCallback)
5.2 使用LiveData监听网络 #
kotlin
class NetworkLiveData(private val context: Context) : LiveData<Boolean>() {
private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
postValue(true)
}
override fun onLost(network: Network) {
postValue(false)
}
}
override fun onActive() {
super.onActive()
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
value = isNetworkAvailable(context)
}
override fun onInactive() {
super.onInactive()
connectivityManager.unregisterNetworkCallback(networkCallback)
}
}
六、最佳实践 #
6.1 使用协程处理网络请求 #
kotlin
class MainViewModel : ViewModel() {
private val repository = NetworkRepository()
private val _result = MutableLiveData<Result<String>>()
val result: LiveData<Result<String>> = _result
fun fetchData(url: String) {
viewModelScope.launch {
_result.value = Result.loading()
try {
val data = repository.fetchData(url)
_result.value = Result.success(data)
} catch (e: Exception) {
_result.value = Result.error(e.message ?: "Unknown error")
}
}
}
}
6.2 处理超时和重试 #
kotlin
suspend fun <T> retryIO(times: Int = 3, block: suspend () -> T): T {
var currentAttempt = 0
var lastException: Exception? = null
while (currentAttempt < times) {
try {
return block()
} catch (e: IOException) {
lastException = e
currentAttempt++
delay(1000L * currentAttempt)
}
}
throw lastException ?: Exception("Unknown error")
}
// 使用
val result = retryIO {
repository.fetchData(url)
}
6.3 缓存策略 #
kotlin
class CacheManager(private val context: Context) {
private val cacheDir = File(context.cacheDir, "network_cache")
fun saveCache(key: String, data: String) {
File(cacheDir, key).writeText(data)
}
fun getCache(key: String): String? {
val file = File(cacheDir, key)
return if (file.exists()) file.readText() else null
}
fun clearCache() {
cacheDir.deleteRecursively()
}
}
七、总结 #
本章介绍了Android网络编程基础:
- 网络权限配置
- 网络状态检查
- HTTP协议基础
- 网络安全配置
- HttpURLConnection使用
- 网络状态监听
- 最佳实践
掌握网络编程基础是开发Android应用的重要技能,下一章将介绍更强大的网络库OkHttp和Retrofit。
最后更新:2026-03-26