1. Android网络请求基础与权限配置在Android开发中网络请求是实现应用与服务器交互的核心功能。与iOS平台不同Android的网络请求实现有其独特的机制和注意事项。我们先从最基础的权限配置开始讲起。1.1 网络权限声明每个需要网络访问的Android应用都必须在AndroidManifest.xml中声明以下基本权限uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE /这里有个重要细节这两个权限都属于普通权限(Normal Permission)系统会在安装时自动授予不需要运行时动态申请。这与需要用户授权的危险权限如相机、位置等有本质区别。注意即使你的应用只需要内网通信也必须声明INTERNET权限。这是Android系统的强制要求。1.2 网络安全配置从Android 7.0API 24开始系统默认只信任系统预装的CA证书。如果你的应用需要与使用自签名证书的服务器通信或者需要限制可信CA的范围就需要配置网络安全策略。在res/xml目录下创建network_security_config.xml文件network-security-config domain-config domain includeSubdomainstrueexample.com/domain trust-anchors certificates srcraw/my_ca/ /trust-anchors /domain-config /network-security-config然后在AndroidManifest.xml中引用这个配置application android:networkSecurityConfigxml/network_security_config ... 1.3 主线程限制Android系统有个重要特性禁止在主线程执行网络操作。如果违反这个规则会抛出NetworkOnMainThreadException。这是因为网络请求是耗时操作会阻塞UI线程导致应用无响应(ANR)。解决方法通常有两种使用AsyncTask已废弃不推荐使用线程池或协程推荐在Kotlin中协程是最优雅的解决方案viewModelScope.launch { try { val result withContext(Dispatchers.IO) { // 执行网络请求 } // 更新UI } catch (e: Exception) { // 处理异常 } }2. 主流HTTP客户端对比与选型Android平台提供了多种HTTP客户端实现各有特点和适用场景。选择适合的客户端对应用的性能和开发效率至关重要。2.1 原生HttpsURLConnection这是Android SDK自带的HTTP客户端支持TLS、流式上传下载等基本功能val url URL(https://api.example.com/data) val connection url.openConnection() as HttpsURLConnection try { connection.requestMethod GET connection.connectTimeout 5000 connection.readTimeout 10000 val responseCode connection.responseCode if (responseCode HttpsURLConnection.HTTP_OK) { val inputStream connection.inputStream // 处理响应数据 } } finally { connection.disconnect() }优点无需额外依赖系统级支持兼容性好缺点API较为底层使用繁琐缺乏高级功能如自动重试、请求拦截等2.2 OkHttpSquare公司开发的现代HTTP客户端已成为Android开发的事实标准implementation com.squareup.okhttp3:okhttp:4.9.3基本用法val client OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .build() val request Request.Builder() .url(https://api.example.com/data) .build() client.newCall(request).enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { // 处理成功响应 } override fun onFailure(call: Call, e: IOException) { // 处理失败 } })高级特性连接池复用GZIP自动压缩响应缓存拦截器链2.3 Retrofit同样是Square开发的类型安全HTTP客户端基于OkHttpimplementation com.squareup.retrofit2:retrofit:2.9.0 implementation com.squareup.retrofit2:converter-gson:2.9.0定义API接口interface ApiService { GET(users/{id}) suspend fun getUser(Path(id) id: String): User POST(users) suspend fun createUser(Body user: User): ResponseUnit }创建Retrofit实例val retrofit Retrofit.Builder() .baseUrl(https://api.example.com/) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() val apiService retrofit.create(ApiService::class.java)2.4 KtorJetBrains开发的Kotlin原生HTTP客户端implementation io.ktor:ktor-client-core:2.0.0 implementation io.ktor:ktor-client-okhttp:2.0.0使用示例val client HttpClient(OkHttp) { install(JsonFeature) { serializer GsonSerializer() } defaultRequest { url(https://api.example.com/) } } suspend fun getUser(id: String): User { return client.get(users/$id) }3. 网络请求架构设计与最佳实践良好的架构设计能让网络请求代码更易维护、测试和扩展。下面介绍几种常见的设计模式。3.1 Repository模式Repository层负责协调数据源网络、数据库等对外提供统一的数据访问接口class UserRepository( private val apiService: ApiService, private val userDao: UserDao ) { suspend fun getUser(id: String): User { // 先检查本地缓存 val cachedUser userDao.getUserById(id) if (cachedUser ! null) { return cachedUser } // 从网络获取 val networkUser apiService.getUser(id) userDao.insertUser(networkUser) return networkUser } }3.2 ViewModel与LiveDataViewModel负责准备和管理UI相关的数据LiveData提供数据观察能力class UserViewModel( private val userRepository: UserRepository ) : ViewModel() { private val _user MutableLiveDataUser() val user: LiveDataUser _user private val _error MutableLiveDataString() val error: LiveDataString _error fun loadUser(id: String) { viewModelScope.launch { try { val user userRepository.getUser(id) _user.value user } catch (e: Exception) { _error.value 加载用户失败: ${e.message} } } } }3.3 依赖注入使用依赖注入框架如Hilt管理网络相关依赖Module InstallIn(SingletonComponent::class) object NetworkModule { Provides Singleton fun provideOkHttpClient(): OkHttpClient { return OkHttpClient.Builder() .addInterceptor(HttpLoggingInterceptor().apply { level HttpLoggingInterceptor.Level.BODY }) .connectTimeout(5, TimeUnit.SECONDS) .build() } Provides Singleton fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit { return Retrofit.Builder() .client(okHttpClient) .baseUrl(https://api.example.com/) .addConverterFactory(GsonConverterFactory.create()) .build() } Provides Singleton fun provideApiService(retrofit: Retrofit): ApiService { return retrofit.create(ApiService::class.java) } }4. 高级网络功能实现4.1 文件上传下载使用OkHttp实现文件上传val requestBody MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart(file, file.name, file.asRequestBody(image/*.toMediaType())) .build() val request Request.Builder() .url(https://api.example.com/upload) .post(requestBody) .build()文件下载并显示进度val client OkHttpClient.Builder() .addNetworkInterceptor { chain - val originalResponse chain.proceed(chain.request()) originalResponse.newBuilder() .body(originalResponse.body?.let { ProgressResponseBody(it) { bytesRead, contentLength - val progress (bytesRead * 100 / contentLength).toInt() // 更新进度 } }) .build() } .build()4.2 WebSocket通信OkHttp支持WebSocket协议val request Request.Builder() .url(wss://echo.websocket.org) .build() val webSocket client.newWebSocket(request, object : WebSocketListener() { override fun onMessage(webSocket: WebSocket, text: String) { // 处理文本消息 } override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { // 连接关闭 } }) // 发送消息 webSocket.send(Hello WebSocket!)4.3 DNS解析优化Android 10支持自定义DNS解析val client OkHttpClient.Builder() .dns(object : Dns { override fun lookup(hostname: String): ListInetAddress { return try { Dns.SYSTEM.lookup(hostname) } catch (e: Exception) { // 备用DNS解析 listOf(InetAddress.getByName(1.1.1.1)) } } }) .build()5. 网络状态监控与优化5.1 网络状态监听注册广播接收器监听网络变化val connectivityManager getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager val networkCallback object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { // 网络可用 } override fun onLost(network: Network) { // 网络断开 } } connectivityManager.registerNetworkCallback( NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(), networkCallback )5.2 网络类型判断检查当前网络类型val capabilities connectivityManager.getNetworkCapabilities(currentNetwork) when { capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) true - { // WiFi网络 } capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) true - { // 移动数据 } else - { // 其他网络 } }5.3 网络请求优化策略缓存策略合理设置Cache-Control头部请求合并合并多个小请求数据压缩使用GZIP压缩图片优化使用WebP格式适当压缩懒加载非关键资源延迟加载val client OkHttpClient.Builder() .cache(Cache( directory File(context.cacheDir, http_cache), maxSize 10L * 1024 * 1024 // 10MB )) .addInterceptor(GzipRequestInterceptor()) .build()6. 常见问题排查与调试技巧6.1 网络请求失败排查步骤检查网络权限是否声明确认设备网络连接正常使用Logcat查看详细错误信息通过Charles或Fiddler抓包分析检查服务器端日志6.2 HTTPS证书问题常见错误SSLHandshakeExceptionCertificateException解决方案确认服务器证书有效检查网络安全配置测试时可以先暂时信任所有证书仅限调试val insecureClient OkHttpClient.Builder() .hostnameVerifier { _, _ - true } .sslSocketFactory( createInsecureSslSocketFactory(), createInsecureTrustManager() ) .build()警告信任所有证书在生产环境中极其危险务必仅在开发调试时使用。6.3 性能优化工具Android Profiler分析网络流量Chrome DevTools调试WebView网络请求OkHttp EventListener监控请求生命周期Firebase Performance Monitoring监控网络性能class TimingEventListener : EventListener() { override fun callStart(call: Call) { // 记录开始时间 } override fun callEnd(call: Call) { // 记录结束时间 } } val client OkHttpClient.Builder() .eventListener(TimingEventListener()) .build()7. 测试与Mock数据7.1 单元测试网络请求使用MockWebServer模拟服务器响应val server MockWebServer() Before fun setup() { server.start() } Test fun testGetUser() runBlocking { server.enqueue(MockResponse() .setBody({id:1,name:Test User}) .setResponseCode(200)) val apiService createApiService(server.url(/)) val user apiService.getUser(1) assertEquals(Test User, user.name) } After fun tearDown() { server.shutdown() }7.2 UI测试中的网络模拟使用IdlingResource同步测试RunWith(AndroidJUnit4::class) class UserActivityTest { get:Rule val activityRule ActivityScenarioRule(UserActivity::class.java) Test fun displayUserName() { val mockWebServer MockWebServer().apply { enqueue(MockResponse() .setBody({id:1,name:Test User}) .setResponseCode(200)) start() } // 注入Mock服务器URL val intent Intent().apply { putExtra(BASE_URL, mockWebServer.url(/).toString()) } activityRule.scenario.onActivity { activity - activity.intent intent } // 验证UI显示 onView(withId(R.id.user_name)) .check(matches(withText(Test User))) } }7.3 离线模式测试测试应用在无网络情况下的表现Before fun disableNetwork() { val connectivityManager getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager val method connectivityManager.javaClass.getDeclaredMethod( setAirplaneMode, Boolean::class.javaPrimitiveType ) method.isAccessible true method.invoke(connectivityManager, true) } Test fun testOfflineBehavior() { // 验证离线状态下的UI表现 } After fun enableNetwork() { // 恢复网络连接 }8. 适配不同Android版本的注意事项8.1 Android 6.0的运行时权限虽然网络权限不需要运行时申请但相关权限如uses-permission android:nameandroid.permission.ACCESS_WIFI_STATE / uses-permission android:nameandroid.permission.CHANGE_WIFI_STATE /需要动态申请if (ContextCompat.checkSelfPermission( this, Manifest.permission.ACCESS_WIFI_STATE ) ! PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_WIFI_STATE), REQUEST_CODE ) }8.2 Android 8.0的后台限制Android 8.0对后台服务有严格限制长时间运行的网络任务应该使用JobScheduler或WorkManager或ForegroundService需显示通知val workRequest PeriodicWorkRequestBuilderSyncWorker( 1, TimeUnit.HOURS ).build() WorkManager.getInstance(context).enqueue(workRequest)8.3 Android 9.0的明文流量限制Android 9.0默认禁止明文HTTP流量解决方法使用HTTPS或配置网络安全策略允许特定域名使用HTTPnetwork-security-config domain-config cleartextTrafficPermittedtrue domain includeSubdomainstrueinsecure.example.com/domain /domain-config /network-security-config8.4 Android 10的隐私变更Android 10引入的隐私变更影响网络功能限制获取设备MAC地址限制访问WiFi扫描结果限制后台启动Activity适配建议检查所有网络相关功能在Android 10设备上的表现使用新的API如ConnectivityManager.NetworkCallback遵循最小权限原则9. 性能监控与线上问题追踪9.1 网络性能指标关键监控指标请求成功率平均响应时间慢请求比例流量消耗9.2 Firebase性能监控集成Firebase Performance Monitoringimplementation com.google.firebase:firebase-perf:20.0.6监控特定网络请求val trace FirebasePerformance.getInstance().newTrace(network_call) trace.start() // 执行网络请求 try { val response apiService.getData() trace.putMetric(response_size, response.body()?.size() ?: 0) } finally { trace.stop() }9.3 异常收集使用Crashlytics收集网络相关异常try { // 网络请求 } catch (e: IOException) { FirebaseCrashlytics.getInstance().log(Network request failed) FirebaseCrashlytics.getInstance().recordException(e) // 处理异常 }9.4 自定义监控系统构建自己的监控体系interface NetworkMonitor { fun onRequestStart(url: String) fun onRequestSuccess(url: String, duration: Long) fun onRequestFailure(url: String, error: Throwable) } class AnalyticsNetworkMonitor : NetworkMonitor { override fun onRequestStart(url: String) { // 记录开始时间 } override fun onRequestSuccess(url: String, duration: Long) { // 上报成功指标 } override fun onRequestFailure(url: String, error: Throwable) { // 上报失败指标 } }10. 未来趋势与新技术10.1 HTTP/3与QUICHTTP/3基于QUIC协议提供更快的连接建立和更好的移动网络性能。OkHttp已支持HTTP/3val client OkHttpClient.Builder() .protocols(listOf(Protocol.HTTP_3, Protocol.HTTP_2, Protocol.HTTP_1_1)) .build()10.2 5G网络优化针对5G网络特点优化利用更高的带宽预加载更多内容适应更低的延迟调整超时时间使用NetworkCapabilities检测5G网络val capabilities connectivityManager.getNetworkCapabilities(network) if (capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_5G) true) { // 5G网络可用调整策略 }10.3 边缘计算将部分计算任务下放到边缘节点使用CDN边缘计算分布式缓存策略地理位置感知的请求路由10.4 机器学习优化使用机器学习预测网络行为预测网络质量变化智能预加载动态调整请求优先级val networkQualityPredictor NetworkQualityPredictor(context) val predictedQuality networkQualityPredictor.predict() when (predictedQuality) { GOOD - // 预加载更多内容 POOR - // 只加载关键内容 }在实际项目中我发现网络请求的稳定性和性能对用户体验影响极大。特别是在弱网环境下合理的重试机制、缓存策略和优雅降级能显著提升应用的可用性。建议在开发早期就建立完善的网络监控体系这样能快速发现和解决线上问题。