gpt4 book ai didi

android - 长时间运行的服务会消耗大量电池

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:52:39 26 4
gpt4 key购买 nike

我开发了一个应用程序,有人提示它太费电了,它是仅次于屏幕的第二大耗电过程。但是,在某些设备中,它不会消耗那么多电池。

我的应用程序所做的所有工作都在服务中。该服务是粘性的并且一直在运行(android系统可能会在资源不足时杀死它或在设备进入休眠状态时暂停它),只要屏幕打开它就会监听加速度计,它不是前台服务并且不持有唤醒锁。

谁能告诉我为什么它需要很多电池?为什么这种情况只发生在某些设备上?

相关代码如下:

public class aListenerService extends Service implements SensorEventListener
{
private BroadcastReceiver mScreenReceiver = new BroadcastReceiver()
{
// if screen was turned on then register to accelerometer
// if screen was turned off then unregister from accelerometer
}

private BroadcastReceiver mPhoneStateReceiver = new BroadcastReceiver()
{
// do something...
}

@Override
public void onCreate()
{
super.onCreate();

// get sensor manager and accelerometer sensor
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

// register accelerometer sensor and receiver
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
IntentFilter screenFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
screenFilter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mScreenReceiver, screenFilter);
registerReceiver(mPhoneStateReceiver, new IntentFilter(INTENT_ACTION_PHONE_STATE));
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);

return Service.START_STICKY;
}

@Override
public void onDestroy()
{
super.onDestroy();

// unregister to sensor and receivers
mSensorManager.unregisterListener(this);
unregisterReceiver(mScreenReceiver);
unregisterReceiver(mPhoneStateReceiver);
}

@Override
public void onSensorChanged(SensorEvent event)
{
// do something...
}
}

最佳答案

始终运行服务在 CPU 和电池方面可能会很昂贵 - 这是服务的缺点之一。特别是如果您包含导致某些 CPU 负载的线程。根据您的应用要求,有一些选项可供选择:

  1. 如果您的服务结果仅在用户可以使用它时相关,您可能会考虑在屏幕打开和关闭事件上停止和启动您的服务 - 或者至少启动和停止包含的线程/处理程序.这可以通过使用 BroadcastReceiver 来完成:

    public class ScreenReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
    // (1) stop service or (2) stop all threads and unregister all event
    // handlers, if the service has to register the screen receiver
    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
    // (1) start service or (2) start all threads and register all event
    // handlers as needed
    }
    }
    }

    请注意,必须以编程方式注册屏幕事件。如果您必须在同一服务内注册屏幕打开和关闭事件,请将其启动为sticky。这样服务实例将被保留。 (示例:电池小部件、天气信息……)

  2. 如果您有一个基于事件的环境,您可以考虑使用 Google Cloud Messaging (GCM)。使用 GCM,您可以从任何服务器向任何已注册的设备发送消息,使其唤醒并处理传入的信息。无需一直轮询信息。

    查看 Google documentation和示例,如果此场景符合您的要求(示例:消息传递应用程序、聊天应用程序...)

  3. 如果您需要定期处理/运行数据/代码,您可能会考虑使用 AlarmManager:

    public void SetAlarm(Context context) {
    AlarmManager manager = (AlarmManager)context.
    getSystemService(Context.ALARM_SERVICE);

    Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
    PendingIntent pendingIntent =
    PendingIntent.getBroadcast(context, 0, intent, 0);

    am.setRepeating(AlarmManager.RTC_WAKEUP,
    System.currentTimeMillis(), 1000 *60 , pendingIntent);
    }

    然而,缺点是它不是短间隔的好选择(比方说小于 30 分钟)。 (示例:电子邮件客户端,...)

所以有一些替代方案。查看您的代码,我可以看到您正在使用传感器做一些事情。如果屏幕关闭,您是否需要传感器信息?或者什么样的事件可以触发您的服务的开始和结束?

如果您真的一直需要结果(例如 GPS 跟踪器),除了优化代码外,您可能别无选择。如果电池电量不足,停止服务可能是有意义的(有关详细信息,请参阅 this)。

祝你好运!

关于android - 长时间运行的服务会消耗大量电池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18170498/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com