【问题标题】:Save energy while app is running应用程序运行时节省能源
【发布时间】:2013-11-07 09:34:55
【问题描述】:

我是 android 编程新手。我编写了一个应用程序,它读取传感器数据(陀螺仪和加速度计),并且在传递值时应该做一些事情。 现在我的问题是电池只运行一小时,sensor_delay_fastestsensor_delay_game 之间没有区别。 是否有可能关闭屏幕灯以节省能源,或者我应该将此应用程序作为服务运行,还是有另一种可能性?我也试过SCREEN_DIM_WAKE_LOCK,没有明显效果。

感谢帮助

古纳尔

【问题讨论】:

    标签: android sensors battery energy


    【解决方案1】:

    您可能将电池消耗归咎于错误的罪魁祸首。 电池消耗的最大恶棍是不在您的主应用循环中使用 Thread.sleep(int ms)

    您的主循环可能每秒运行数千次,而实际上实施帧限制可以将次数减少到 24-60(对于流畅的动画),或者对于非常基本的应用程序甚至可以低至 10-20。

    考虑一下:如果你不让你的线程休眠,你实际上是在让你的应用程序(和主循环)尽可能快地运行尽可能多的次数。如果没有睡眠,您的应用会消耗 100% 的可用资源来运行,即使它实际上什么也没做。

    Here's a good starting tutorial,这是一个实现示例(来自链接)。不要紧张它有多长;没有 cmets 会短很多...

    public void run() {
        Canvas canvas;
        Log.d(TAG, "Starting game loop");
        // initialise timing elements for stat gathering
        initTimingElements();
    
        long beginTime;     // the time when the cycle begun
        long timeDiff;      // the time it took for the cycle to execute
        int sleepTime;      // ms to sleep (<0 if we're behind)
        int framesSkipped;  // number of frames being skipped 
    
        sleepTime = 0;
    
        while (running) {
            canvas = null;
            // try locking the canvas for exclusive pixel editing
            // in the surface
            try {
                canvas = this.surfaceHolder.lockCanvas();
                synchronized (surfaceHolder) {
                    beginTime = System.currentTimeMillis();
                    framesSkipped = 0;  // resetting the frames skipped
                    // update game state 
                    this.gamePanel.update();
                    // render state to the screen
                    // draws the canvas on the panel
                    this.gamePanel.render(canvas);              
                    // calculate how long did the cycle take
                    timeDiff = System.currentTimeMillis() - beginTime;
                    // calculate sleep time
                    sleepTime = (int)(FRAME_PERIOD - timeDiff);
    
                    if (sleepTime > 0) {
                        // if sleepTime > 0 we're OK
                        try {
                            // send the thread to sleep for a short period
                            // very useful for battery saving
                            Thread.sleep(sleepTime);    
                        } catch (InterruptedException e) {}
                    }
    
                    while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
                        // we need to catch up
                        this.gamePanel.update(); // update without rendering
                        sleepTime += FRAME_PERIOD;  // add frame period to check if in next frame
                        framesSkipped++;
                    }
    
                    if (framesSkipped > 0) {
                        Log.d(TAG, "Skipped:" + framesSkipped);
                    }
                    // for statistics
                    framesSkippedPerStatCycle += framesSkipped;
                    // calling the routine to store the gathered statistics
                    storeStats();
                }
            } finally {
                // in case of an exception the surface is not left in 
                // an inconsistent state
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }   // end finally
        }
    }
    

    【讨论】:

    • 但我没有任何基于传感器值的动画。该应用仅在达到限制时读取传感器数据并播放声音
    • 即便如此,让您的线程休眠让应用程序有机会在传感器事件之间休息(取决于您的传感器事件是否使用“同步”)。仅仅因为上面的例子是在动画上下文中使用的,并不意味着它是唯一的用途。尽管几乎什么都没做,您的应用程序仍然可能会最大限度地使用它的 CPU。这不是您问题的唯一答案。这个 Reddit 线程还有很多内容:reddit.com/r/Android/comments/1dastm/…
    • 没有问题。也很抱歉,我现在回想起来,Reddit 线程更适合用户而不是开发人员
    猜你喜欢
    • 1970-01-01
    • 2021-12-31
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    相关资源
    最近更新 更多