Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android请求优先级调度

Android中四种主流的请求优先级调度详解

作者:时小雨

这篇文章主要为大家详细介绍了Android中四种主流的优先级调度方案,并提供完整可运行的Kotlin实现代码,感兴趣的小伙伴可以跟随小编一起学习一下

在移动应用开发中,有效管理任务优先级是提升用户体验的关键技术。本文将全面解析Android中四种主流的优先级调度方案,并提供完整可运行的Kotlin实现代码。

一、线程池 + 优先级队列(核心方案)

完整实现代码

import java.util.concurrent.*

// 优先级任务基类
abstract class PriorityRunnable(
    private val priority: Int // 值越大优先级越高
) : Runnable, Comparable<PriorityRunnable> {
    override fun compareTo(other: PriorityRunnable): Int {
        return other.priority.compareTo(priority) // 降序排列
    }
}

// 优先级线程池
class PriorityThreadPool {
    private val executor: ThreadPoolExecutor

    companion object {
        private const val CORE_POOL_SIZE = 4
        private const val MAX_POOL_SIZE = 8
        private const val KEEP_ALIVE_TIME = 60L
    }

    init {
        val queue = PriorityBlockingQueue<Runnable>()
        executor = ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            queue
        ).apply {
            allowCoreThreadTimeOut(true)
        }
    }

    fun execute(task: PriorityRunnable) {
        executor.execute(task)
    }
}

// 使用示例
fun testPriorityThreadPool() {
    val pool = PriorityThreadPool()

    // 低优先级任务
    pool.execute(object : PriorityRunnable(1) {
        override fun run() {
            println("低优先级任务开始")
            Thread.sleep(1000)
            println("低优先级任务完成")
        }
    })

    // 高优先级任务(后提交但先执行)
    Thread.sleep(100) // 确保低优先级任务先入队
    pool.execute(object : PriorityRunnable(10) {
        override fun run() {
            println("高优先级任务开始")
            Thread.sleep(500)
            println("高优先级任务完成")
        }
    })
}

执行流程

关键点总结

二、Handler + Message优先级(UI任务专用)

完整实现代码

import android.os.Handler
import android.os.Looper
import android.os.Message

class PriorityHandler(looper: Looper) : Handler(looper) {

    companion object {
        const val HIGH_PRIORITY = 10
        const val NORMAL_PRIORITY = 5
        const val LOW_PRIORITY = 1
    }

    // 按优先级插入消息队列
    override fun sendMessageAtTime(msg: Message, uptimeMillis: Long): Boolean {
        msg.data?.putInt("priority", msg.arg1) // 存储优先级
        
        synchronized(queue) {
            var cur = queue
            var prev: Message? = null
            
            // 遍历找到插入位置
            while (cur != null && (cur.data?.getInt("priority") ?: 0) >= msg.arg1) {
                prev = cur
                cur = cur.next
            }
            
            // 插入操作
            msg.next = cur
            prev?.next = msg ?: run { queue = msg }
        }
        return true
    }
}

// 使用示例
fun testPriorityHandler() {
    val handler = PriorityHandler(Looper.getMainLooper())

    // 低优先级任务
    handler.obtainMessage().apply {
        arg1 = PriorityHandler.LOW_PRIORITY
        handler.sendMessage(this)
    }

    // 高优先级任务
    handler.obtainMessage().apply {
        arg1 = PriorityHandler.HIGH_PRIORITY
        handler.sendMessage(this) // 将插入队列头部
    }
    
    // 消息处理
    object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.arg1) {
                PriorityHandler.HIGH_PRIORITY -> 
                    println("处理高优先级UI任务")
                PriorityHandler.LOW_PRIORITY -> 
                    println("处理低优先级UI任务")
            }
        }
    }
}

适用场景

三、网络请求优先级(双方案对比)

Volley实现方案

val queue = Volley.newRequestQueue(context)

// 高优先级请求
val highPriorityRequest = object : StringRequest(
    Method.GET, 
    "https://api.example.com/user",
    { response -> /* 处理响应 */ },
    { error -> /* 处理错误 */ }
) {
    override fun getPriority() = Priority.HIGH
}

// 低优先级请求
val lowPriorityRequest = object : ImageRequest(
    "https://cdn.example.com/image.jpg",
    { bitmap -> /* 显示图片 */ },
    0, 0, null,
    { error -> /* 处理错误 */ }
) {
    override fun getPriority() = Priority.LOW
}

queue.add(highPriorityRequest)
queue.add(lowPriorityRequest)

OkHttp实现方案

val client = OkHttpClient()

// 自定义调度器
val dispatcher = Dispatcher().apply {
    maxRequests = 64
    maxRequestsPerHost = 16
}

val client = OkHttpClient.Builder()
    .dispatcher(dispatcher)
    .build()

// 带优先级的请求封装
class PriorityRequest(
    private val request: Request,
    private val priority: Int
) : Comparable<PriorityRequest> {
    override fun compareTo(other: PriorityRequest) = 
        other.priority.compareTo(priority)
}

// 使用优先级队列
val priorityQueue = PriorityBlockingQueue<PriorityRequest>()

// 执行请求
fun enqueueRequest(priorityRequest: PriorityRequest) {
    client.newCall(priorityRequest.request).enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response) {
            // 处理响应
        }
        override fun onFailure(call: Call, e: IOException) {
            // 处理失败
        }
    })
}

网络方案对比

特性VolleyOkHttp+自定义
优先级实现内置支持需自定义封装
适用请求类型小型请求大文件下载/上传
复杂度
灵活性一般

四、WorkManager后台任务调度

完整实现代码

import androidx.work.*

// 高优先级工作器
class HighPriorityWorker(
    context: Context,
    params: WorkerParameters
) : Worker(context, params) {

    override fun doWork(): Result {
        // 执行重要后台任务
        return Result.success()
    }
}

// 低优先级工作器
class LowPriorityWorker(
    context: Context,
    params: WorkerParameters
) : Worker(context, params) {

    override fun doWork(): Result {
        // 执行普通后台任务
        return Result.success()
    }
}

// 任务调度管理
class WorkScheduler(private val context: Context) {

    fun scheduleHighPriorityWork() {
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresBatteryNotLow(true)
            .build()

        val request = OneTimeWorkRequestBuilder<HighPriorityWorker>()
            .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
            .setConstraints(constraints)
            .build()

        WorkManager.getInstance(context).enqueue(request)
    }

    fun scheduleLowPriorityWork() {
        val request = OneTimeWorkRequestBuilder<LowPriorityWorker>()
            .setConstraints(
                Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.UNMETERED) // 仅WiFi
                    .build()
            )
            .build()

        WorkManager.getInstance(context)
            .beginWith(request)
            .enqueue()
    }
}

适用场景

五、综合对比与选型指南

方案适用场景执行线程优势注意事项
线程池+优先级队列CPU密集型计算后台线程精细控制,灵活性高需手动管理生命周期
Handler优先级UI相关任务主线程无缝集成UI系统仅限同Looper任务
网络请求优先级网络操作网络线程行业标准方案协议层限制
WorkManager持久化后台任务系统分配系统级优化,省电兼容性好最低API级别限制

最佳实践与性能优化

优先级分层设计

object PriorityLevel {
    const val CRITICAL = 100 // 用户直接操作
    const val HIGH = 80      // 实时反馈
    const val MEDIUM = 50    // 常规任务
    const val LOW = 10       // 后台清理
}

避免优先级反转

executor.execute {
    val future = pool.submit(task)
    future.get(500, TimeUnit.MILLISECONDS) // 设置超时
}

监控与调优工具

// 监控线程池状态
fun monitorThreadPool(executor: ThreadPoolExecutor) {
    Timer().scheduleAtFixedRate({
        println("""
            活跃线程: ${executor.activeCount}
            队列任务: ${executor.queue.size}
            完成数: ${executor.completedTaskCount}
        """.trimIndent())
    }, 0, 5000)
}

混合调度策略

fun scheduleMixedTask(task: Task) {
    when (task.type) {
        TaskType.UI_CRITICAL -> mainHandler.sendPriorityMessage(task)
        TaskType.NETWORK -> volleyQueue.add(task)
        TaskType.BACKGROUND -> WorkManager.enqueue(task)
        else -> threadPool.execute(task)
    }
}

前沿扩展:协程优先级调度

Kotlin协程提供更现代的调度方案:

// 创建优先级调度器
val priorityDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()

// 带优先级启动协程
fun launchPriorityTask(priority: Int) = runBlocking {
    val job = launch(priorityDispatcher) {
        setTaskPriority(priority) // 自定义优先级逻辑
        // 任务代码
    }
    
    // 优先级控制
    job.invokeOnCompletion { 
        println("任务完成,优先级:$priority") 
    }
}

// 使用结构化并发管理
suspend fun fetchDataWithPriority() = coroutineScope {
    val urgent = async(Dispatchers.IO) { fetchUrgentData() }
    val normal = async(Dispatchers.IO) { fetchNormalData() }
    
    // 优先处理紧急数据
    val result = urgent.await().process()
    normal.await() // 等待普通数据完成
    return result
}

协程优势

总结与关键点

核心原则

技术选型

性能关键点

扩展方向

到此这篇关于Android中四种主流的请求优先级调度详解的文章就介绍到这了,更多相关Android请求优先级调度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文