Flutter中如何在本地通知展示API数据加载进度?
在通知栏展示数据加载进度的实现方案
Android 平台实现步骤
1. 创建通知渠道(Android 8.0+ 必需)
Android 8.0及以上版本要求所有通知归属到指定渠道,否则无法正常显示:
private fun createProgressNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( "PROGRESS_CHANNEL_ID", "数据加载进度", NotificationManager.IMPORTANCE_LOW // 低优先级,避免打扰用户 ).apply { description = "实时展示数据加载进度" } val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
2. 用前台服务执行加载并更新进度
耗时的API请求不能放在UI线程,通过前台服务后台执行任务,同时同步更新通知进度:
class DataLoadService : Service() { private val notificationManager by lazy { getSystemService(NOTIFICATION_SERVICE) as NotificationManager } private val serviceScope = CoroutineScope(Dispatchers.IO + Job()) override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { // 初始化进度通知模板 val notificationBuilder = NotificationCompat.Builder(this, "PROGRESS_CHANNEL_ID") .setContentTitle("正在更新数据") .setContentText("加载中...") .setSmallIcon(R.drawable.ic_download) .setPriority(NotificationCompat.PRIORITY_LOW) .setProgress(100, 0, false) // false为确定进度,true表示模糊加载状态 // 启动前台服务,绑定通知 startForeground(1, notificationBuilder.build()) // 模拟API加载流程(替换为你的实际请求逻辑) serviceScope.launch { for (progress in 0..100 step 10) { delay(500) // 模拟加载耗时 // 更新通知进度 notificationBuilder.setProgress(100, progress, false) notificationBuilder.setContentText("已加载 ${progress}%") notificationManager.notify(1, notificationBuilder.build()) } // 加载完成后更新通知状态 notificationBuilder.setContentTitle("数据更新完成") .setContentText("所有数据已加载完毕") .setProgress(0, 0, false) // 隐藏进度条 notificationManager.notify(1, notificationBuilder.build()) stopForeground(STOP_FOREGROUND_REMOVE) // 停止前台服务 stopSelf() } return START_NOT_STICKY } override fun onBind(intent: Intent?): IBinder? = null override fun onDestroy() { serviceScope.cancel() super.onDestroy() } }
3. 点击按钮启动服务
在Activity的按钮点击事件中触发加载流程:
updateButton.setOnClickListener { val intent = Intent(this, DataLoadService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(intent) } else { startService(intent) } }
iOS 平台实现步骤
1. 请求通知权限
先向用户申请通知权限,否则无法展示通知:
import UserNotifications func requestNotificationPermission() { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { granted, error in if let error = error { print("权限请求失败: \(error.localizedDescription)") } } }
2. 创建并更新进度通知
通过后台任务执行加载,实时更新通知内容:
func startDataLoadWithProgress() { // 初始化通知内容 let content = UNMutableNotificationContent() content.title = "正在更新数据" content.body = "加载中..." content.sound = .none // 添加初始通知 let requestID = "DataLoadProgressRequest" let request = UNNotificationRequest(identifier: requestID, content: content, trigger: nil) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("添加通知失败: \(error.localizedDescription)") return } // 模拟API加载流程(替换为你的实际请求逻辑) DispatchQueue.global().async { for progress in 0...100 step 10 { Thread.sleep(forTimeInterval: 0.5) // 模拟加载耗时 DispatchQueue.main.async { // 更新通知内容 let updatedContent = UNMutableNotificationContent() updatedContent.title = "正在更新数据" updatedContent.body = "已加载 \(progress)%" updatedContent.sound = .none // 用相同ID覆盖旧通知 let updatedRequest = UNNotificationRequest(identifier: requestID, content: updatedContent, trigger: nil) UNUserNotificationCenter.current().add(updatedRequest) { _ in } } } // 加载完成后更新通知 DispatchQueue.main.async { let finishContent = UNMutableNotificationContent() finishContent.title = "数据更新完成" finishContent.body = "所有数据已加载完毕" finishContent.sound = UNNotificationSound.default let finishRequest = UNNotificationRequest(identifier: requestID, content: finishContent, trigger: nil) UNUserNotificationCenter.current().add(finishRequest) { _ in } } } } }
3. 按钮点击触发加载
绑定按钮点击事件,启动加载流程:
updateButton.addTarget(self, action: #selector(startLoad), for: .touchUpInside) @objc func startLoad() { startDataLoadWithProgress() }
通用注意事项
- 避免UI阻塞:所有加载和进度更新逻辑必须放在后台线程,防止界面卡顿。
- 真实进度计算:如果API支持分块/分段加载,可通过已加载字节数/总字节数、已加载页数/总页数计算真实进度;无明确总数据量时,可使用模糊进度模式(Android设置
setProgress第三个参数为true,iOS可显示"加载中..."无具体百分比)。 - 异常处理:加载失败时要及时更新通知,告知用户失败原因,可添加重试按钮跳转至重试逻辑。
内容的提问来源于stack exchange,提问作者saif rehman
相关产品推荐
相关产品推荐

