Android 如何实现持续运行1分钟的循环Worker以处理网络连接需求
实现方案
现有代码的问题
- 时间单位换算错误:
System.nanoTime()返回的是纳秒数值,你之前写的5*60是秒级数值,没有做单位转换,导致循环条件几乎立刻不成立,无法达到运行1分钟的效果 - 无循环间隔:空循环会疯狂占用后台CPU资源,同时日志会无间隔重复打印,无法实现你要的每秒输出一次日志的需求
- 未控制重试状态:没有设置全局状态标记控制前端重试按钮的可点击状态
具体实现代码
首先你需要先定义一个全局状态标记,可以用ViewModel的LiveData或者SharedPreferences存储,用来控制重试按钮是否可点击,这里以SharedPreferences为例:
@NonNull @Override public Result doWork() { Context context = getApplicationContext(); // 启动Worker时,先把重试按钮设为不可点击 SharedPreferences sp = context.getSharedPreferences("app_config", Context.MODE_PRIVATE); sp.edit().putBoolean("retry_enable", false).apply(); Log.e("MyWork", "Starting Worker"); boolean connectSuccess = false; // 循环60次,每次间隔1秒,总计1分钟 for (int i = 1; i <= 60; i++) { Log.e("MyWork", "Running Worker in 1 Minute with seconds - " + i); // 这里写你连接服务器的逻辑 connectSuccess = connectToServer(); if (connectSuccess) { // 连接成功直接跳出循环 break; } try { // 每次尝试后等待1秒再重试 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); // 线程被中断直接返回失败,同时开放重试 sp.edit().putBoolean("retry_enable", true).apply(); return Result.failure(); } } Log.e("MyWork", "Done Running Worker in 1 Minute"); // 1分钟结束,不管成功失败都开放重试按钮 sp.edit().putBoolean("retry_enable", true).apply(); if (connectSuccess) { // 连接成功返回成功结果 return Result.success(); } else { // 连接失败返回失败结果,上层可以监听Worker结果更新UI return Result.failure(); } } // 你自己的服务器连接逻辑实现 private boolean connectToServer() { // 实际连接代码写在这里,连接成功返回true,失败返回false return false; }
前端按钮控制逻辑
你在页面里可以监听SharedPreferences的retry_enable字段变化,或者监听Worker的运行状态,来设置重试按钮的setEnabled属性,值为false的时候拦截用户点击,值为true的时候允许点击触发重试。
注意事项
- 不要直接返回
Result.retry(),Worker的默认重试策略是指数退避间隔重试,不符合你1分钟内连续尝试的需求,1分钟后如果用户点击重试,你再手动触发新的Worker启动即可 - 如果你的连接逻辑是异步实现,可以用
CountDownLatch在Worker中等待异步执行结果,避免Worker提前结束运行 - 如果需要考虑页面重建的状态同步,建议用ViewModel存储重试按钮的可点击状态,配合LiveData做UI更新
内容的提问来源于stack exchange,提问作者Anne
相关产品推荐
相关产品推荐

