#android #performance
#Android #Производительность
Вопрос:
Требуется записывать позицию каждые 90 секунд и записывать ее в базу данных (sqlite), и если сеть доступна, то вызывать API, даже если приложение закрыто. Какой будет наилучший возможный способ добиться этого? Должен ли я запускать службу намерений? Или я должен использовать диспетчер аварийных сигналов. Я где-то читал, что alarm Manager следует использовать, только если продолжительность составляет более 10 минут.
Комментарии:
1. используйте запущенную службу
2. Вы могли бы попробовать использовать обычный сервис и обработчик. Где обработчик выполняет необходимые задачи каждые 90 секунд, и обработчик может находиться внутри службы, которая будет работать в фоновом режиме, если она запущена с флагом «START_STICKY»;
Ответ №1:
Я предлагаю использовать AlarmManager, поскольку его можно запустить, даже если устройство находится в спящем режиме. Обратите внимание, что для API v > 19 доставка сигналов тревоги является неточной, и для достижения этого необходимо использовать setExact api . Смотрите
Примечание: Начиная с API 19, время срабатывания, переданное этому методу, рассматривается как неточное: сигнал тревоги не будет доставлен до этого времени, но может быть отложен и доставлен некоторое время спустя. ОС будет использовать эту политику для того, чтобы «пакетные» сигналы тревоги вместе по всей системе, сводя к минимуму количество раз, когда устройство должно «просыпаться», и минимизируя использование батареи. В общем, сигналы тревоги, запланированные в ближайшем будущем, не будут отложены до тех пор, пока сигналы тревоги, запланированные в далеком будущем. С новой политикой пакетной обработки гарантии заказа доставки не так сильны, как раньше. Если приложение устанавливает несколько сигналов тревоги, возможно, что фактический порядок доставки этих сигналов тревоги может не соответствовать порядку запрошенных сроков доставки. Если ваше приложение предъявляет строгие требования к порядку, существуют другие API, которые вы можете использовать для получения необходимого поведения; см. setWindow (int, long, long, PendingIntent) и setExact (int, long, PendingIntent).
Ответ №2:
Alarm Manager будет идеальным выбором для вашей ситуации. Зарегистрированные сигналы тревоги сохраняются, пока устройство находится в спящем режиме, но будут удалены, если оно выключено и перезагружено. Таким образом, вы можете использовать это для выполнения своей работы с интервалом в 90 секунд. Это может нарушить интервал только в первый раз после перезагрузки устройства.
Ответ №3:
Другим способом, который я обнаружил, было использование диспетчера заданий Firebase. Это лучший вариант для устройств, работающих на marshmallow или более поздних версиях. Его легко интегрировать и настраивать. https://github.com/firebase/firebase-jobdispatcher-android
Ответ №4:
Служба — это компонент приложения, который может выполнять длительные операции в фоновом режиме и не предоставляет пользовательский интерфейс.
https://developer.android.com/guide/components/services.html
Диспетчер аварийных сигналов предназначен для случаев, когда вы хотите, чтобы код вашего приложения запускался в определенное время, даже если ваше приложение в данный момент не запущено. Диспетчер аварийных сигналов удерживает блокировку пробуждения процессора до тех пор, пока выполняется метод onReceive () приемника аварийных сигналов. Это гарантирует, что телефон не перейдет в режим ожидания, пока вы не закончите обработку трансляции.
https://developer.android.com/reference/android/app/AlarmManager.html
Используйте сервис.
Ответ №5:
Вы используете службу намерений и компоненты Broadcastreceiver, потому что эти компоненты прослушивают только непрерывно, даже если вы закрываете приложение.
И вы хотите получать что-то каждые 90 секунд, поэтому используйте Alarm Manager.
AlarmManager manager = (AlarmManager) (context)
.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, YourAlarmReceuver.class);
//alarmIntent.putExtra("syncData", favoritesArrayList);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 90*1000, pendingIntent);
Ваш класс приемника, подобный этому
public class SyncAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent stIntent = new Intent(context,
YourService.class);
context.startService(stIntent);
}
И ваш класс обслуживания намерений, подобный этому
public class DataSyncService extends IntentService {
public DataSyncService() {
super(DataSyncService.class.getName());
// TODO Auto-generated constructor stub
}
@Override
protected void onHandleIntent(Intent intent) {
//write your logic here
// get the location and update the database
}
}
Вы также должны создать экземпляр alarm Manager, загрузка которого завершена.
Комментарии:
1. Это не будет работать надежно.
WakeLock
Не предусмотрено дляService
, поэтому устройство может снова перейти в спящий режим, прежде чем оно сможет быть выполнено.2. Диспетчер сигналов тревоги должен работать, даже если устройство находится в спящем режиме. Но если устройство перезапускается, то оно теряет все сигналы тревоги, для этого нам нужно создать экземпляр диспетчера сигналов тревоги при завершении загрузки.
3. Да,
AlarmManager
будет работать, так как во времяWakeLock
гарантируетсяonReceive()
, но устройство может вернуться в спящий режим сразу послеonReceive()
завершения. Вот почему вы должны предоставитьWakeLock
дляService
либо вручную, либо с помощьюWakefulBroadcastReceiver
вспомогательного класса.4. Как сказал @earthw0rmjim, здесь следует использовать WakefulBroadcastReceiver.
5. Кроме того,
setInexactRepeating()
это худший из возможных вариантов здесь. Сигналы тревоги не будут точными, и они не будут работать с Doze.