设备进入睡眠状态时,Android会降低前台服务的速度 [英] Android slows down foreground service when device sleeps

查看:103
本文介绍了设备进入睡眠状态时,Android会降低前台服务的速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天来,我一直在以下方面苦苦挣扎:我想在屏幕关闭的情况下使用Android设备上的重力传感器来计算运动模式.我正在使用从前台启动的绑定服务(带有通知Android 8使其保持运行状态),并且在屏幕打开时一切正常.即使该应用程序未在前台运行,也可以正常工作.

For a few days now im struggling with the following: I want to count movement patterns using the gravity sensor on an Android device while the screen is off. I am using a bound service that I start in the foreground (with a notification for Android 8 to keep it running) and everything works fine when the screen is on. Even if the App is not running in the foreground everything works fine.

但是,一旦关闭显示器,就会发生非常奇怪的事情:传感器数据仍在处理中,并且移动进行了一定程度的扩展,但是结果非常糟糕且不准确.另外,如果再次打开屏幕,则该应用程序的行为非常奇怪.有时,该应用程序会按预期运行,但有时似乎会延迟处理旧的传感器事件,并在以后进行计数.从那时起,整个算法运行不平稳.有趣的是:如果插入了设备,并且我在Android Studio的控制台中观察到了一切,即使屏幕关闭了,一切也都可以完美运行.但是,如果拔掉设备的电源,结果将再次变为错误.

However, as soon as the display is turned off, very strange things start to happen: The sensor data is still processed and movement counted to some extend but the results are very bad and inaccurate. Also, if the screen is turned on again, the app behaves very strange. Sometimes the app works as expected but sometimes it seems that old sensor events are processed delayed and counted later. The whole algorithm is not running smoothly from this time on. What is also interesting: If the device is plugged in and I observe everything with the console in Android Studio everything works just perfect, even if the screen is off. However, if the device is unplugged, the results become wrong again.

我尝试了很多事情:使用IntentService在主线程上,在另一个线程上运行所有内容,将应用设置为白名单上的

I tried a lot of things: Running everything on the main thread, on another thread, using an IntentService, setting the App on the whitelist for Doze, not sending data to the MainActivity while the screen is turned off, and followed this guide (I am developing on an Galaxy J5) - but nothing worked. It seems that either the SensorFusion algorithms of the Android system shut down in Standby even if there is a registered listener or that Samsung has some battery optimization running in the background and limits CPU operations. Is there something else that could cause this behavior? So running fine if the app is active, if it is in the background, but not when the device is in sleep?

也许还值得一提:我正在为Cordova开发一个插件.

Also maybe interesting to mention: I am developing a plugin for Cordova.

这是我的代码

public class SensorPlugin extends CordovaPlugin implements ServiceClass.Delegate {

    public void initialize() {
      ...
      Intent serviceIntent = new Intent(applicationContext, ServiceClass.class);
      applicationContext.bindService(serviceIntent, serviceConnection, 
          Context.BIND_AUTO_CREATE);
    }

    public void start() {
        serviceClass.startMeasuring();
    }

    @Override
    public void updateMovementCount(int count) {
        ...
    };

}

Service.class

public class ServiceClass extends Service implements OtherClass.Delegate {

    private volatile boolean isMeasuring;
    private volatile double gravityX;
    private volatile double gravityY;
    private volatile double gravityZ;

    public IBinder onBind(Intent intent) {
        sensorManager = (SensorManager) getApplicationContext().
            getSystemService(Context.SENSOR_SERVICE);

        startForeground(1, buildNotification());
        return mBinder;
    }

    public void startMeasuring() {
        assert sensorManager != null;
        Sensor gravity = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
        sensorManager.registerListener(this, gravity, 
            SensorManager.SENSOR_DELAY_GAME);

        isTracking = true;

        SensorThread sensorThread = new SensorThread();
        sensorThread();
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        gravityX = event.values[0];
        gravityY = event.values[1];
        gravityZ = event.values[2];
    }

    // This is an interface method from another class that I wrote
    // (see below). For which I set this class as delegate and as soon
    // as the other class finds a pattern in the data it calls this method
    @Override
    public void movementPatternDidChange(int count) {
        // Usually I send this count to the main class with
        // the same delegation pattern
        delegate.updateMovementCount(count);
    }

    class SensorProcessingThread extends Thread {
        Handler handler = new Handler();

        // I use another runnable here, as I only want to process 10
        // sensor events per second. The sensor manager usually returns
        // way more which I don't need.
        private Runnable sensorProcessingRunnable = new Runnable() {
            public void run() {
                otherClass.processMotionData(gravityX, gravityY, gravityZ);
                if (isMeasuring) {
                    handler.postDelayed(this, 100);
                }
            }
        };

        @Override
        public void run() {
            if (!isMeasuring) {
                return;
            }

            handler.postDelayed(sensorProcessingRunnable, 100);
        }
    }

}


编辑

与此同时,我进行了很多测试.我现在正在使用 Apache Commons Primitives Collections 以获得更好的性能(而不是大型FastUtil,它也导致过去的错误).


Edit

I tested a lot in the meantime. I am now using the Apache Commons Primitives Collections for a better performance (instead of the large FastUtil which also caused this error in the past).

我还在两台设备上测试了该应用程序,它们是相当老的LG G2和Galaxy J5.两者的问题是相同的.因此可能不是特定于制造商的. Android Studio Profiler报告这两种设备上的CPU使用率平均为1-3%,因此我认为可能不是造成过载的原因.我还测试了TimerTask和Timer而不是Runnable和Handler,但效果不佳.

I also tested the app on two devices, a rather old LG G2 and the Galaxy J5. The problem is the same on both. So probably not manufacturer specific. The Android Studio Profiler reports a CPU usage of average 1-3% on both devices, so I assume an overload is likely not the cause. I also tested a TimerTask and Timer instead of a Runnable and Handler, which did not work as well.

还有一点很有趣:我试图通过Wifi 如此处所述所述,即使设备处于休眠状态且屏幕已关闭,该应用程序也可以正常运行.调试此问题非常困难,因为即使没有连接电缆,我在调试该应用程序后也能正常运行.我不知道还能做什么.

What is also very interesting: I tried to debug the App over Wifi as explained here, and the App works absolutely fine, even if the device sleeps and the screen is turned off. It is so difficult to debug this issue, because the App behaves fine as soon as I am debugging it even without a cable attached. I have no idea what I could do else.

推荐答案

对于遇到类似问题的每个人:我终于找到了解决方案.

For everyone with a similar problem: I finally found the solution.

我认为这在Android文档中没有得到很好的解释,也不是很直观,但是仍然有必要设置部分唤醒锁以防止CPU休眠. 介绍了如何设置唤醒锁.仅前台服务不足以保持时间紧迫的进程运行.

I think it is not well explained in the Android documentation, and not very intuitive either, but it is still necessary to set a partial wake lock to prevent the CPU from sleeping. This explains how to set a wake lock. A foreground service alone is not enough to keep a time-critical process running.

这篇关于设备进入睡眠状态时,Android会降低前台服务的速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆