El servicio de larga duración consume mucha batería
He desarrollado una aplicación y algunas personas se quejan de que se necesita demasiada batería, es el segundo proceso más consumidor después de la pantalla. Sin embargo, en algunos dispositivos no consume mucha batería.
Todo el trabajo de mi aplicación es en un servicio. El servicio es pegajoso y está funcionando todo el tiempo (el sistema androide puede matar cuando tiene recursos bajos o pausa cuando el dispositivo se va a dormir), tiene oyente al acelerómetro mientras la pantalla está encendida, no es servicio de primer plano Y no tiene wakelock.
- Incapaz de crear servicio java.lang.NullPointerException
- Servicio vs IntentService
- Cómo mantener la escucha de notificaciones push en Android en segundo plano
- START_STICKY para IntentService
- ¿Por qué mis métodos ServiceConnection nunca se ejecutan?
¿Puede alguien decirme por qué se necesita mucha batería? ¿Y por qué sucede esto sólo en algunos de los dispositivos?
Aquí está el código relevante:
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... } }
- Programación de salida HDMI para pantalla dual
- ¿Cómo puede el servicio de Android actualizar la interfaz de usuario de la actividad que lo inició?
- Android: servicio de primer plano frente a wakeLock
- La función "Optimización de aplicaciones" de Samsung mata aplicaciones de fondo después de 3 días
- Servicio de Android puede ser obligar sin iniciar?
- Null intent redelivered to Service onStartCommand ()
- Enviar datos de la actividad al servicio en ejecución
- Servicio en android?
Ejecución de servicios todo el tiempo puede ser caro en relación con la CPU y la batería – que es una de las desventajas de un servicio. En particular, si incluye subprocesos que causan algo de carga de la CPU. Hay algunas opciones para elegir, dependiendo de los requisitos de la aplicación:
-
Si el resultado de su servicio sólo es relevante en el momento en que el usuario puede consumirlo, podría pensar en detener e iniciar el servicio en la pantalla en y fuera de los eventos o al menos iniciar y detener los subprocesos / manipuladores incluidos. Esto se puede hacer usando un
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 } } }
Tenga en cuenta que los eventos de pantalla tienen que registrarse mediante programación. Si tiene que registrar la pantalla en y fuera de los eventos dentro del mismo servicio, inícielo como pegajoso . De esta forma se mantendrá la instancia de servicio. ( Ejemplos : widgets de batería, información meteorológica, …)
-
En caso de tener un entorno basado en eventos, podría pensar en usar Google Cloud Messaging (GCM). Con GCM puede enviar un mensaje desde cualquiera de sus servidores a cualquier dispositivo registrado que lo haga despertar y procesar la información entrante. No hay necesidad de hacer encuestas de información todo el tiempo.
Consulte la documentación y ejemplos de GoogleGoogles, si este escenario se ajusta a sus necesidades ( ejemplos : aplicación de mensajería, aplicación de chat, …)
-
Si necesita procesar / ejecutar datos / código regularmente, podría pensar en usar un
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); }
Sin embargo, la desventaja es que no es una buena opción para intervalos cortos (digamos menos de 30 minutos). ( Ejemplos : cliente de correo electrónico, …)
Así que hay algunas alternativas. Mirando su código, puedo ver que está haciendo algo con sensores. ¿Necesita la información del sensor, si la pantalla está apagada? ¿O qué tipo de eventos podrían desencadenar el inicio y fin de su servicio?
Si realmente necesita los resultados todo el tiempo (por ejemplo, para un rastreador GPS), probablemente no hay otra opción que optimizar su código. Puede ser que tenga sentido parar el servicio, si la batería es baja (véase esto para más detalles).
¡Buena suerte!
- Android: ¿puedo abrir la aplicación Instagram en hashtag?
- El archivo se guarda en UTF-8 pero símbolos extraños en lengua rusa