uni-app 启动定时任务后切换后台不运行问题
uni-app 启动定时任务后切换后台不运行问题
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | win10 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
HBuilderX类型:正式
HBuilderX版本号:3.2.2
手机系统:Android
手机系统版本号:Android 7.0
手机厂商:小米
手机机型:小米6,小米10s
页面类型:vue
打包方式:云端
示例代码:
doSettime(){
//启动定时任务
this.smsTitle='运行中';
//设置是否在运行中
this.isrun=!this.isrun;
if(this.isrun==false){
if(this.g_wakelock != null && this.g_wakelock.isHeld()) {
this.g_wakelock.release();
this.g_wakelock = null;
}
clearInterval(this.inTime);
this.smsTitle='获取短信';
return false;
}
const that=this;
this.inTime=setInterval(
()=>{
this.getMessage();
//this.getSmsMaxTime()
}
,300000);
},
async getMessage(){
//不同机型可能获取不全
//查看权限是否已允许
var that=this;
//判断时间在20点-8点取消获取短信
var nowHours=new Date().getHours();
if(nowHours>=18 || nowHours<=8){
return false;
}
//
//获取短信内容
var Context = plus.android.runtimeMainActivity();
var res = plus.android.invoke('android.support.v4.app.ActivityCompat', 'checkSelfPermission', Context, 'android.permission.READ_SMS');
var PERMISSIONS_STORAGE = new Array();
PERMISSIONS_STORAGE.push('android.permission.READ_SMS');
// res == -1 时为询问状态,询问时会走Show 和 Hidden
if (res != '0') {
plus.android.invoke('android.support.v4.app.ActivityCompat', 'requestPermissions', Context, PERMISSIONS_STORAGE, 1);
} else {
that.sms=[];
var main = plus.android.runtimeMainActivity();
var Uri = plus.android.importClass('android.net.Uri');
var ContactsContract = plus.android.importClass('android.provider.ContactsContract');
var uri = Uri.parse('content://sms/');
var cr = main.getContentResolver();
plus.android.importClass(cr);
var cur = cr.query(uri, null, null, null, null);
plus.android.importClass(cur);
//cur.moveToFirst();
that.count++;
that.smsTitle='运行'+that.count+'次';
while (cur.moveToNext()) {
// 时间
var index_date = cur.getColumnIndex("date");
var date = cur.getString(index_date);
//如果是原内容,就退出
if(date<=that.title){
break;
}
//类型1接收 2发送
var index_Type = cur.getColumnIndex('type');
var type = cur.getString(index_Type);
if(type!=1){
continue;
}
var index_Address = cur.getColumnIndex('address');
var address = cur.getString(index_Address);
var isAllowSms=this.allowSms.indexOf(address);
if(isAllowSms===-1){
continue;
}
//短信内容
var index_Body = cur.getColumnIndex('body');
var body = cur.getString(index_Body);
//console.log(address, body, type);
that.sms.push({
address:address,
body:body,
type:type,
date:date
})
// 收件人
// 短信内容
// 短信的类型
}
cur.close();
if(that.sms.length!=0){
var phpres=await that.$myRequest({
url:'api/user/smsAdd',
method:'POST',
data:{list:JSON.stringify(that.sms)}
});
that.title=phpres.data.data.maxtime;
}
}
}
操作步骤:
- app启动一个定时任务后,app切换后台后,他就不运行了。只能有前台运行。
预期结果:
- 希望app在后台也能运行,
实际结果:
- 现在的时候任务,把app切换到后台,就停止运行了
bug描述:
- app启动一个定时任务后,app切换后台后,他就不运行了。只能有前台运行。
更多关于uni-app 启动定时任务后切换后台不运行问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
现在定时任务,去掉 async await 。然后访问接口用的Uni.request现在好像可以了。
更多关于uni-app 启动定时任务后切换后台不运行问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个典型的Android后台限制问题。在Android系统中,应用切换到后台后,系统会限制其CPU和网络活动以节省电量,导致setInterval定时器无法正常执行。
解决方案:
1. 使用原生后台服务
创建Android原生Service来执行后台任务:
// 创建后台服务
const main = plus.android.runtimeMainActivity();
const Intent = plus.android.importClass('android.content.Intent');
const intent = new Intent(main, plus.android.importClass('com.example.BackgroundService'));
main.startService(intent);
2. 使用uni-app的plus API保持后台运行
// 申请后台运行权限
plus.android.requestPermissions(['android.permission.WAKE_LOCK'], function(e){
// 获取电源锁
const PowerManager = plus.android.importClass('android.os.PowerManager');
const pm = main.getSystemService(Context.POWER_SERVICE);
const wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp:WakeLock");
wakeLock.acquire();
});
3. 使用WorkManager(推荐)
在Android 6.0+上,使用WorkManager实现可靠的后台任务:
// 配置周期性任务
const WorkManager = plus.android.importClass('androidx.work.WorkManager');
const PeriodicWorkRequest = plus.android.importClass('androidx.work.PeriodicWorkRequest');
const Constraints = plus.android.importClass('androidx.work.Constraints');
const NetworkType = plus.android.importClass('androidx.work.NetworkType');
const constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
const workRequest = new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build();
WorkManager.getInstance(main).enqueue(workRequest);
4. 前台服务通知
对于需要持续运行的任务,使用前台服务:
// 创建前台服务
const NotificationManager = plus.android.importClass('android.app.NotificationManager');
const NotificationChannel = plus.android.importClass('android.app.NotificationChannel');
const NotificationCompat = plus.android.importClass('android.support.v4.app.NotificationCompat');
// 创建通知渠道(Android 8.0+必需)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
const channel = new NotificationChannel("channel_id", "后台服务", NotificationManager.IMPORTANCE_LOW);
const notificationManager = main.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
5. 修改manifest.json配置
在uni-app项目的manifest.json中添加:
{
"app-plus": {
"distribute": {
"android": {
"permissions": [
"android.permission.WAKE_LOCK",
"android.permission.FOREGROUND_SERVICE"
]
}
}
}
}

