仅对于图片加载场景
- 使用 OkHttp 替代 Glide 默认网络加载,优先使用 HTTP2
- 扩大
maxRequestsPerHost可同一时间加载更多任务,默认只有 5 个,对于加载图片的场景远远不够 - 扩大
GlideExecutor的加载任务,可同时请求更多数据,默认只有 4 个,在网络好时或者高端机适当扩大 - 使用 HttpDns,避免劫持和 加快 DNS 解析,DNS 解析可提前初始化
- 做好机型适配,避免低端机 OOM
操作步骤
引入 OkHttp 替代 Glide 默认加载
implementation com.github.bumptech.glide:okhttp3-integration:version
优化 OkhttpClient 加载配置
@GlideModule
class NetMonitorGlideModule : AppGlideModule() {
private var okHttpClient: OkHttpClient? = null
override fun applyOptions(context: Context, builder: com.bumptech.glide.GlideBuilder) {
// 动态获取线程数
val config = getConfig(context)
val sourceExecutor = GlideExecutor.newSourceBuilder()
.setThreadCount(config.glideThreadCount)
.setName("source-executor")
.setUncaughtThrowableStrategy(GlideExecutor.UncaughtThrowableStrategy.LOG)
.build()
builder.setSourceExecutor(sourceExecutor)
}
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
if (okHttpClient == null) {
okHttpClient = createGlideOkhttpClient(context)
}
// 替换 Glide 的默认网络加载器
registry.replace(
GlideUrl::class.java,
InputStream::class.java,
OkHttpUrlLoader.Factory(okHttpClient!!)
)
}
private fun createGlideOkhttpClient(context: Context): OkHttpClient {
// 动态并发控制
val config = getConfig(context)
val dispatcher = okhttp3.Dispatcher().apply {
maxRequestsPerHost = config.maxRequestsPerHost
}
return OkHttpClient.Builder()
.dispatcher(dispatcher)
.connectTimeout(8, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.connectionPool(
ConnectionPool(
config.maxIdleConnections, // 保留更多连接
5L, TimeUnit.MINUTES
)
)
.retryOnConnectionFailure(true)
.dns(AliDNS.getInstance(context))
.build()
}
override fun isManifestParsingEnabled(): Boolean {
return false
}
/**
* 根据设备内存情况动态计算并发数
* 低端机 (<= 4GB RAM): 限制为 5,防止 OOM 和 CPU 抢占导致 UI 卡顿
* 高端机 (> 4GB RAM): 开启 6+,追求极致加载速度
*/
private fun getConfig(context: Context): Config {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as? android.app.ActivityManager
// 获取总内存
val memInfo = android.app.ActivityManager.MemoryInfo()
activityManager?.getMemoryInfo(memInfo)
// 4GB = 4 * 1024 * 1024 * 1024L
val threshold = 4L * 1024 * 1024 * 1024L
// 动态计算最佳线程数 (策略:CPU核心数 + 1,但限制在 6~10 之间) ---
val cpuCount = Runtime.getRuntime().availableProcessors()
// 比如:
// 4核手机 -> max(6, 5) = 6 个线程
// 8核手机 -> min(10, 9) = 9 个线程
val calculatedThreads = min(10, max(6, cpuCount + 1))
return if (memInfo.totalMem > threshold) {
Config(
glideThreadCount = calculatedThreads,
maxRequestsPerHost = 15,
maxIdleConnections = 10
)
} else {
Config(
glideThreadCount = calculatedThreads,
maxRequestsPerHost = 10,
maxIdleConnections = 5
)
}
}
private data class Config(
val glideThreadCount: Int,
val maxRequestsPerHost: Int,
val maxIdleConnections: Int
)
}