Android中四種主流的請(qǐng)求優(yōu)先級(jí)調(diào)度詳解
在移動(dòng)應(yīng)用開發(fā)中,有效管理任務(wù)優(yōu)先級(jí)是提升用戶體驗(yàn)的關(guān)鍵技術(shù)。本文將全面解析Android中四種主流的優(yōu)先級(jí)調(diào)度方案,并提供完整可運(yùn)行的Kotlin實(shí)現(xiàn)代碼。
一、線程池 + 優(yōu)先級(jí)隊(duì)列(核心方案)
完整實(shí)現(xiàn)代碼
import java.util.concurrent.*
// 優(yōu)先級(jí)任務(wù)基類
abstract class PriorityRunnable(
private val priority: Int // 值越大優(yōu)先級(jí)越高
) : Runnable, Comparable<PriorityRunnable> {
override fun compareTo(other: PriorityRunnable): Int {
return other.priority.compareTo(priority) // 降序排列
}
}
// 優(yōu)先級(jí)線程池
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()
// 低優(yōu)先級(jí)任務(wù)
pool.execute(object : PriorityRunnable(1) {
override fun run() {
println("低優(yōu)先級(jí)任務(wù)開始")
Thread.sleep(1000)
println("低優(yōu)先級(jí)任務(wù)完成")
}
})
// 高優(yōu)先級(jí)任務(wù)(后提交但先執(zhí)行)
Thread.sleep(100) // 確保低優(yōu)先級(jí)任務(wù)先入隊(duì)
pool.execute(object : PriorityRunnable(10) {
override fun run() {
println("高優(yōu)先級(jí)任務(wù)開始")
Thread.sleep(500)
println("高優(yōu)先級(jí)任務(wù)完成")
}
})
}
執(zhí)行流程

關(guān)鍵點(diǎn)總結(jié)
- 使用
PriorityBlockingQueue實(shí)現(xiàn)任務(wù)自動(dòng)排序 - 通過
compareTo方法定義優(yōu)先級(jí)規(guī)則 - 核心線程可超時(shí)回收(
allowCoreThreadTimeOut) - 適合CPU密集型任務(wù)處理
二、Handler + Message優(yōu)先級(jí)(UI任務(wù)專用)
完整實(shí)現(xiàn)代碼
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
}
// 按優(yōu)先級(jí)插入消息隊(duì)列
override fun sendMessageAtTime(msg: Message, uptimeMillis: Long): Boolean {
msg.data?.putInt("priority", msg.arg1) // 存儲(chǔ)優(yōu)先級(jí)
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())
// 低優(yōu)先級(jí)任務(wù)
handler.obtainMessage().apply {
arg1 = PriorityHandler.LOW_PRIORITY
handler.sendMessage(this)
}
// 高優(yōu)先級(jí)任務(wù)
handler.obtainMessage().apply {
arg1 = PriorityHandler.HIGH_PRIORITY
handler.sendMessage(this) // 將插入隊(duì)列頭部
}
// 消息處理
object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.arg1) {
PriorityHandler.HIGH_PRIORITY ->
println("處理高優(yōu)先級(jí)UI任務(wù)")
PriorityHandler.LOW_PRIORITY ->
println("處理低優(yōu)先級(jí)UI任務(wù)")
}
}
}
}
適用場(chǎng)景
- 界面刷新任務(wù)優(yōu)先于數(shù)據(jù)預(yù)處理
- 用戶操作響應(yīng)優(yōu)先于后臺(tái)日志上傳
- 動(dòng)畫效果優(yōu)先于靜態(tài)內(nèi)容加載
三、網(wǎng)絡(luò)請(qǐng)求優(yōu)先級(jí)(雙方案對(duì)比)
Volley實(shí)現(xiàn)方案
val queue = Volley.newRequestQueue(context)
// 高優(yōu)先級(jí)請(qǐng)求
val highPriorityRequest = object : StringRequest(
Method.GET,
"https://api.example.com/user",
{ response -> /* 處理響應(yīng) */ },
{ error -> /* 處理錯(cuò)誤 */ }
) {
override fun getPriority() = Priority.HIGH
}
// 低優(yōu)先級(jí)請(qǐng)求
val lowPriorityRequest = object : ImageRequest(
"https://cdn.example.com/image.jpg",
{ bitmap -> /* 顯示圖片 */ },
0, 0, null,
{ error -> /* 處理錯(cuò)誤 */ }
) {
override fun getPriority() = Priority.LOW
}
queue.add(highPriorityRequest)
queue.add(lowPriorityRequest)
OkHttp實(shí)現(xiàn)方案
val client = OkHttpClient()
// 自定義調(diào)度器
val dispatcher = Dispatcher().apply {
maxRequests = 64
maxRequestsPerHost = 16
}
val client = OkHttpClient.Builder()
.dispatcher(dispatcher)
.build()
// 帶優(yōu)先級(jí)的請(qǐng)求封裝
class PriorityRequest(
private val request: Request,
private val priority: Int
) : Comparable<PriorityRequest> {
override fun compareTo(other: PriorityRequest) =
other.priority.compareTo(priority)
}
// 使用優(yōu)先級(jí)隊(duì)列
val priorityQueue = PriorityBlockingQueue<PriorityRequest>()
// 執(zhí)行請(qǐng)求
fun enqueueRequest(priorityRequest: PriorityRequest) {
client.newCall(priorityRequest.request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
// 處理響應(yīng)
}
override fun onFailure(call: Call, e: IOException) {
// 處理失敗
}
})
}
網(wǎng)絡(luò)方案對(duì)比
| 特性 | Volley | OkHttp+自定義 |
|---|---|---|
| 優(yōu)先級(jí)實(shí)現(xiàn) | 內(nèi)置支持 | 需自定義封裝 |
| 適用請(qǐng)求類型 | 小型請(qǐng)求 | 大文件下載/上傳 |
| 復(fù)雜度 | 低 | 中 |
| 靈活性 | 一般 | 高 |
四、WorkManager后臺(tái)任務(wù)調(diào)度
完整實(shí)現(xiàn)代碼
import androidx.work.*
// 高優(yōu)先級(jí)工作器
class HighPriorityWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
// 執(zhí)行重要后臺(tái)任務(wù)
return Result.success()
}
}
// 低優(yōu)先級(jí)工作器
class LowPriorityWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
// 執(zhí)行普通后臺(tái)任務(wù)
return Result.success()
}
}
// 任務(wù)調(diào)度管理
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()
}
}
適用場(chǎng)景
- 高優(yōu)先級(jí):即時(shí)消息同步、支付結(jié)果通知
- 低優(yōu)先級(jí):日志上傳、非緊急數(shù)據(jù)預(yù)取
- 特性:系統(tǒng)級(jí)調(diào)度,支持任務(wù)鏈?zhǔn)綀?zhí)行
五、綜合對(duì)比與選型指南
| 方案 | 適用場(chǎng)景 | 執(zhí)行線程 | 優(yōu)勢(shì) | 注意事項(xiàng) |
|---|---|---|---|---|
| 線程池+優(yōu)先級(jí)隊(duì)列 | CPU密集型計(jì)算 | 后臺(tái)線程 | 精細(xì)控制,靈活性高 | 需手動(dòng)管理生命周期 |
| Handler優(yōu)先級(jí) | UI相關(guān)任務(wù) | 主線程 | 無(wú)縫集成UI系統(tǒng) | 僅限同Looper任務(wù) |
| 網(wǎng)絡(luò)請(qǐng)求優(yōu)先級(jí) | 網(wǎng)絡(luò)操作 | 網(wǎng)絡(luò)線程 | 行業(yè)標(biāo)準(zhǔn)方案 | 協(xié)議層限制 |
| WorkManager | 持久化后臺(tái)任務(wù) | 系統(tǒng)分配 | 系統(tǒng)級(jí)優(yōu)化,省電兼容性好 | 最低API級(jí)別限制 |
最佳實(shí)踐與性能優(yōu)化
優(yōu)先級(jí)分層設(shè)計(jì)
object PriorityLevel {
const val CRITICAL = 100 // 用戶直接操作
const val HIGH = 80 // 實(shí)時(shí)反饋
const val MEDIUM = 50 // 常規(guī)任務(wù)
const val LOW = 10 // 后臺(tái)清理
}
避免優(yōu)先級(jí)反轉(zhuǎn)
executor.execute {
val future = pool.submit(task)
future.get(500, TimeUnit.MILLISECONDS) // 設(shè)置超時(shí)
}
- 使用超時(shí)機(jī)制
- 限制高優(yōu)先級(jí)任務(wù)比例
監(jiān)控與調(diào)優(yōu)工具
// 監(jiān)控線程池狀態(tài)
fun monitorThreadPool(executor: ThreadPoolExecutor) {
Timer().scheduleAtFixedRate({
println("""
活躍線程: ${executor.activeCount}
隊(duì)列任務(wù): ${executor.queue.size}
完成數(shù): ${executor.completedTaskCount}
""".trimIndent())
}, 0, 5000)
}
混合調(diào)度策略
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)
}
}
前沿?cái)U(kuò)展:協(xié)程優(yōu)先級(jí)調(diào)度
Kotlin協(xié)程提供更現(xiàn)代的調(diào)度方案:
// 創(chuàng)建優(yōu)先級(jí)調(diào)度器
val priorityDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
// 帶優(yōu)先級(jí)啟動(dòng)協(xié)程
fun launchPriorityTask(priority: Int) = runBlocking {
val job = launch(priorityDispatcher) {
setTaskPriority(priority) // 自定義優(yōu)先級(jí)邏輯
// 任務(wù)代碼
}
// 優(yōu)先級(jí)控制
job.invokeOnCompletion {
println("任務(wù)完成,優(yōu)先級(jí):$priority")
}
}
// 使用結(jié)構(gòu)化并發(fā)管理
suspend fun fetchDataWithPriority() = coroutineScope {
val urgent = async(Dispatchers.IO) { fetchUrgentData() }
val normal = async(Dispatchers.IO) { fetchNormalData() }
// 優(yōu)先處理緊急數(shù)據(jù)
val result = urgent.await().process()
normal.await() // 等待普通數(shù)據(jù)完成
return result
}
協(xié)程優(yōu)勢(shì):
- 輕量級(jí)線程管理
- 結(jié)構(gòu)化并發(fā)控制
- 掛起機(jī)制減少資源競(jìng)爭(zhēng)
- 與Jetpack組件深度集成
總結(jié)與關(guān)鍵點(diǎn)
核心原則:
- 用戶交互任務(wù) > 視覺反饋 > 數(shù)據(jù)預(yù)加載 > 后臺(tái)清理
- 避免低優(yōu)先級(jí)任務(wù)餓死
- 根據(jù)設(shè)備狀態(tài)動(dòng)態(tài)調(diào)整
技術(shù)選型:

性能關(guān)鍵點(diǎn):
- 控制高并發(fā)場(chǎng)景的優(yōu)先級(jí)反轉(zhuǎn)
- 監(jiān)控線程池隊(duì)列堆積
- 合理設(shè)置線程生命周期
擴(kuò)展方向:
- 基于電池狀態(tài)的動(dòng)態(tài)優(yōu)先級(jí)調(diào)整
- 機(jī)器學(xué)習(xí)驅(qū)動(dòng)的智能調(diào)度
- 跨進(jìn)程優(yōu)先級(jí)傳遞
到此這篇關(guān)于Android中四種主流的請(qǐng)求優(yōu)先級(jí)調(diào)度詳解的文章就介紹到這了,更多相關(guān)Android請(qǐng)求優(yōu)先級(jí)調(diào)度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android使用百度地圖出現(xiàn)閃退及定位時(shí)顯示藍(lán)屏問題的解決方法
這篇文章主要介紹了Android使用百度地圖出現(xiàn)閃退及定位時(shí)顯示藍(lán)屏問題的解決方法,需要的朋友可以參考下2018-01-01
android表格效果之ListView隔行變色實(shí)現(xiàn)代碼
首先繼承SimpleAdapter再使用重載的Adapter來(lái)達(dá)到效果,其實(shí)主要是需要重載SimpleAdapter,感興趣的朋友可以研究下,希望本文可以幫助到你2013-02-02
Kotlin基礎(chǔ)學(xué)習(xí)之Deprecated與Suppress注解使用
這篇文章主要給大家介紹了關(guān)于Kotlin基礎(chǔ)學(xué)習(xí)之Deprecated與Suppress注解使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Android?Studio實(shí)現(xiàn)彈窗設(shè)置
這篇文章主要為大家詳細(xì)介紹了Android?Studio實(shí)現(xiàn)彈窗設(shè)置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Android實(shí)現(xiàn)透明度可變的標(biāo)題欄效果
這篇文章主要介紹了Android實(shí)現(xiàn)透明度可變的標(biāo)題欄效果的相關(guān)資料,具有一定的參考價(jià)值,需要的朋友可以參考下2016-02-02
Android實(shí)現(xiàn)獲取meta-data和build.gradle的值
這篇文章主要介紹了Android實(shí)現(xiàn)獲取meta-data和build.gradle的值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-03-03
Android中使用SeekBar拖動(dòng)條實(shí)現(xiàn)改變圖片透明度(代碼實(shí)現(xiàn))
這篇文章主要介紹了Android中使用SeekBar拖動(dòng)條實(shí)現(xiàn)改變圖片透明度,需要的朋友可以參考下2020-01-01
Android使用Sqlite存儲(chǔ)數(shù)據(jù)用法示例
這篇文章主要介紹了Android使用Sqlite存儲(chǔ)數(shù)據(jù)的方法,結(jié)合實(shí)例形式分析了Android操作SQLite數(shù)據(jù)庫(kù)的相關(guān)步驟與操作技巧,需要的朋友可以參考下2016-11-11

