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"
                ]
            }
        }
    }
}
回到顶部