ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【Jetpack Compose进阶学与练】第18课 权限、WorkManager后台任务;Compose当中处理系统服务

2026/9/24 17:31:18 拓冰建站 浏览量
【Jetpack Compose进阶学与练】第18课 权限、WorkManager后台任务;Compose当中处理系统服务 前言前面学习UI、列表分页、Canvas绘图、动画。真实App开发还需要和Android系统交互动态申请运行时权限后台定时执行任务在Compose环境如何调用系统服务。注意Compose只是UI层Android平台底层系统API依旧保留原样。知识点清单Compose当中申请危险权限使用accompanist‑permission库普通静态权限AndroidManifest.xml直接声明WorkManager后台任务定义Worker构造WorkRequestwork队列调度Compose页面触发后台工作WorkManager调度观察WorkResults获取系统服务振动、剪贴板在Compose当中的写法前置依赖 build.gradledependencies { // accompanist权限 implementation com.google.accompanist:accompanist-permissions:0.34.0 // work‑manager implementation androidx.work:work-runtime-ktx:2.10.0 }完整示例源码importandroid.content.Contextimportandroidx.work.CoroutineWorkerimportandroidx.work.WorkerParametersimportandroidx.work.OneTimeWorkRequestBuilderimportandroidx.work.WorkManagerimportandroidx.work.WorkInfoimportandroidx.compose.foundation.layout.Arrangementimportandroidx.compose.foundation.layout.Columnimportandroidx.compose.foundation.layout.fillMaxSizeimportandroidx.compose.foundation.layout.paddingimportandroidx.compose.material3.Buttonimportandroidx.compose.material3.Textimportandroidx.compose.runtime.Composableimportandroidx.compose.runtime.getValueimportandroidx.compose.runtime.mutableStateOfimportandroidx.compose.runtime.rememberimportandroidx.compose.runtime.setValueimportandroidx.compose.ui.Alignmentimportandroidx.compose.ui.Modifierimportandroidx.compose.ui.platform.LocalContextimportcom.google.accompanist.permissions.ExperimentalPermissionsApiimportcom.google.accompanist.permissions.rememberPermissionState//后台Worker任务classSimpleBackUpWorker(context:Context,params:WorkerParameters):CoroutineWorker(context,params){overridesuspendfundoWork():Result{//后台执行耗时逻辑备份、同步数据returnResult.success()}}OptIn(ExperimentalPermissionsApi::class)ComposablefunSystemServiceDemoScreen(){valcontextLocalContext.current//申请通知权限Android13 POST_NOTIFICATIONSvalnotificationPermissionStaterememberPermissionState(android.Manifest.permission.POST_NOTIFICATIONS)varworkStatusTextbyremember{mutableStateOf(任务尚未调度)}Column(modifierModifier.fillMaxSize().padding(24.dp),verticalArrangementArrangement.spacedBy(16.dp),horizontalAlignmentAlignment.CenterHorizontally){Button(onClick{if(!notificationPermissionState.hasPermission){notificationPermissionState.launchPermissionRequest()}}){Text(请求通知权限)}Text(if(notificationPermissionState.hasPermission)✅通知权限已授予else❌通知权限尚未授予)Button(onClick{//构建一次性后台任务valworkReqOneTimeWorkRequestBuilderSimpleBackUpWorker().build()WorkManager.getInstance(context).enqueue(workReq)workStatusText已经提交后台任务}){Text(提交一次后台备份任务)}Text(textworkStatusText)}}逐行解读权限分类普通权限直接在AndroidManifest.xml声明安装时自动授予运行时不用弹窗申请。危险运行时权限相机、位置、通知(Android13)、存储必须运行时弹窗向用户申请。在Compose当中不要自己写Activity的onRequestPermissionsResult回调使用 accompanist‑permissions rememberPermissionState 封装权限请求完全以声明式方式处理权限。launchPermissionRequest() 触发系统权限弹窗 hasPermission 读取当前是否已经拥有权限。LocalContextval context LocalContext.currentCompose没有this.context通过LocalContext获取当前Activity的Context调用系统服务、WorkManager都需要Context。⚠️不要保存LocalContext到ViewModel容易内存泄漏仅在Compose组件内部临时读取。WorkManager后台任务CoroutineWorker 协程版本Worker doWork() 是后台执行入口suspend可以写挂起函数适合网络、IO返回Result.success() / Result.failure()OneTimeWorkRequestBuilder 一次性后台任务还有 PeriodicWorkRequestBuilder 用于周期性重复任务WorkManager.getInstance(context).enqueue() 入队调度系统根据资源、电量条件择机执行不能保证立刻执行WorkManager不是定时器。可以通过 WorkManager.getWorkInfoByIdFlow() 订阅任务状态Flow观察任务运行、成功、失败。系统服务调用剪贴板、振动器同样使用LocalContext拿到context之后获取系统服务。valvibratorcontext.getSystemService(Context.VIBRATOR_SERVICE)asandroid.os.Vibrator注意部分系统服务本身还需要配套权限。生命周期注意点Compose页面销毁之后如果页面内LaunchedEffect里面的协程会自动取消但是WorkManager任务独立于页面即使App退后台、页面关闭任务依旧会被系统调度运行。容易踩坑❌ 在ViewModel保存LocalContext持有页面Activity的Context引用发生内存泄漏ViewModel里面优先使用Application Context。❌ 误以为WorkManager可以当做精准定时器系统会受电量、省电策略限制不能精确控制毫秒级执行时间。❌ 权限只写代码调用 launchPermissionRequest() 忘记在AndroidManifest.xml声明弹窗不会出现。❌ Worker里面直接操作Compose UIWorker跑在后台线程绝对不允许更新界面后台任务完成之后可以发通知或者写入数据库UI层观察数据库Flow来刷新页面。✅ accompanist‑permissions声明式权限LocalContext获取上下文CoroutineWorker写后台任务WorkManager任务独立页面生命周期。多元化习题练习习题1【基础‑改错题】为什么不要把LocalContext保存到ViewModel成员变量答案LocalContext拿到的是Activity上下文当页面销毁Activity释放ViewModel持有Activity引用会造成严重内存泄漏ViewModel中应当使用Application的全局Context。解读Compose获取context只能在可组合函数内部临时读取。习题2【基础‑代码修改题】声明一个周期性后台任务每12小时执行一次备份写出构建对象那一行答案valperiodicWorkandroidx.work.PeriodicWorkRequestBuilderSimpleBackUpWorker(12,java.util.concurrent.TimeUnit.HOURS).build()解读周期任务最小间隔是15分钟系统底层限制不能设置太短。习题3【进阶‑补充代码题】如果希望UI能够实时观察WorkManager后台任务的执行状态应该怎么做答案调用 workManager.getWorkInfoByIdFlow(workId) 拿到FlowViewModel订阅或者UI直接collectAsStateWithLifecycle读取WorkInfo的stateRUNNING / SUCCEEDED / FAILED更新界面提示。解读后台任务不要直接回调修改UI通过Flow响应式通知UI。习题4【综合‑逻辑应用题】危险运行时权限Manifest已经添加声明但是运行时没有弹窗申请会是什么后果答案直接执行需要该权限的系统API的时候会直接抛出异常App崩溃危险权限除清单声明之外运行时必须主动弹窗向用户申请拿到用户授权之后才可以调用对应的系统能力。解读Manifest只是注册真正授权必须运行时弹窗。习题5【概念简答题】WorkManager后台任务App已经划掉进程杀掉之后还能不能执行答案在系统允许的条件下没有被省电策略、后台限制完全禁止WorkManager依然可以由系统调度拉起进程执行Worker它专门用于适配不同Android版本的后台约束但是不能100%保证一定运行受厂商省电策略影响很大。解读国产手机后台限制对WorkManager影响比较明显。本节课知识点总结Compose只是UI层Android底层系统API仍然不变使用accompanist‑permissions库做运行时权限申请声明式写法替代旧的Activity回调。LocalContext.current在可组合项里面获取上下文禁止保存到ViewModel防止内存泄漏ViewModel优先Application上下文。WorkManager用于可靠后台任务CoroutineWorker支持suspend协程分为一次性任务OneTimeWorkRequest和周期性PeriodicWorkRequest注意周期任务有系统最小时间限制。Worker后台线程不能更新UI后台任务完成可以写数据库UI层通过Flow观察数据变化刷新界面。WorkManager执行时机受Android系统省电策略、国产厂商后台管控影响不能当做高精度定时器。下一课预告第19课 单元测试与UI测试ViewModel单元测试 Compose界面测试基础