0

Я работаю над приложением для исследовательских целей. Мы хотим отслеживать некоторые действия пользователя на телефоне: если некоторые действия легко деактивируются с широковещательными приемниками, мы также хотим проверить текущие запущенные приложения. Это приложение работает только на устройствах Android, работающих под управлением Android 5.0 или ниже.Повторяющаяся фоновая задача Android - Handler vs AlarmManager

Моя проблема заключается в том, что я отправляю Runnable Obj в обработчик, Runnable снова записывает себя в обработчик после HALF_SECOND (см. Код для подробностей). В runnable я получаю информацию и отправляю их в IntentService для выполнения работы.

Все работает нормально: приложение запускается при загрузке, обработчике и runnable выполняет свою работу в фоновом режиме, ЕСЛИ я не открываю основное действие. Приложение может продолжать работать в течение нескольких дней, но если я открою основное мероприятие, а затем закрою его из «недавних открытых действий» с помощью салфетки или из диспетчера задач памяти, обработчика и стоп-стопа, даже если они не вызваны/доступ к ним (они находятся в отдельной службе). Кроме того, не всегда выполняется вызов onDestroy (активности или услуги). Чтение в Интернете Я понимаю, что салфетки или диспетчер задач удаляют приложение из памяти, а не всегда вызывают onDestory.

То, что я хочу достичь, - это заставить обработчик начать работу сразу после закрытия основной деятельности.

То, что я пробовал, заключается в том, чтобы поместить некоторую проверку в метод onPause активности, убедившись, что вы удалите эту проверку, если вызов onStart снова вызван (например, если приложение переключается с вертикального на горизонтальный, или если кнопка дома нажата, а затем приложение снова откроется). Также был реализован способ заставить обработчика отправить намерение «ImAlive» на широковещательный приемник, который должен перезапустить службу, которая запускает обработчик, если намерения не доходят до завершения обратного отсчета. К сожалению, как только основная активность прекращается, даже трансляция автоматически незарегистрируется и уничтожается.

Мой вопрос в том, есть ли способ создать что-то, что может заставить мой обработчик перезапустить, если активность закрыта? Или есть какой-то другой образец, который может помочь мне в качестве обходного пути для того, чего я хочу достичь? Поскольку я обрабатываю данные каждые полторы секунды, лучше читать обработчик, потому что таймер увеличивает небольшой интервал до большего интервала, а AlarmManager недостаточно точен для очень малого интервала.

Что я хочу достичь, это нечто похожее на Facebook, Instagram, Whatsapp, приложение Telegram, которые всегда находятся в памяти, и даже если вы вынуждены их прекратить, через несколько секунд снова туда ... как?

Мы не заинтересованы в проблемах с батареями из-за непрерывного опроса данных. Что касается исследовательских целей, мы не против, если телефон, на котором мы тестируем последние 2 дня подряд, 1 день или 12 часов или меньше.

Здесь код: OnBootService запускается из широковещательного приемника, объявленного в манифесте, когда принимаются действия onBootCompleted и ShutDown, чтобы запустить и остановить обработчик.

public class OnBootService extends Service{ 
    private static final Handler handler = new Handler(); 
    private final long HALF_SEC = 500; 
    private RunnableTest r = null; 
    private Context myContext = this; 
    private final String TAG = "BootService"; 
    // Extras 
    public static final String START = "start"; 
    public static final String STOP = "stop"; 

    @Override 
    public IBinder onBind(Intent intent){ 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flag, int startId){ 

     String action = intent.getAction(); 

     switch(action){ 
      case START: startHandler(); 
       break; 
      case STOP: stopHandler(); 
       break; 
     } 

     return START_NOT_STICKY; 
    } 

    private void startHandler(){ 
     if(r == null){ 
      r = new RunnableTest(); 

      handler.post(r); 
      Log.i(TAG, "----Handler started!"); 
     } 

    } 

    private void stopHandler(){  
     if(r != null){ 
      Log.i(TAG, "----calling STOP"); 
      handler.removeCallbacks(r); 
      r = null; 
     } 

    } 

    private class RunnableTest implements Runnable { 
     private String TAG = "RunnableTest"; 

     public RunnableTest(){} 

     @Override 
     public void run(){ 
      handler.removeCallbacks(this); 

      // Do stuff 
      Intent i = new Intent(myContext, MyIntentService.class); 
      i.putExtra("addStuff", myStuff); 
      myContext.startService(i); 

      handler.postDelayed(this, HALF_SEC); 
     } 

    } 

Деятельность пуста: весь метод переопределен, чтобы понять правильный жизненный цикл деятельности, а еще пуст.

public class MainActivity extends AppCompatActivity { 
    private final String TAG = "Activity"; 
    private Context myContext = this; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    // access a file and get stored information to show 

     setContentView(R.layout.activity_main); 
     Toast.makeText(getBaseContext(), "Application open successfully", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    protected void onRestart(){ 
     super.onRestart(); 
     Log.e(TAG, "----onRestart Called"); 
    } 

    @Override 
    protected void onStart(){ 
     super.onStart(); 
     Log.e(TAG, "----onSTART Called"); 
    } 

    @Override 
    protected void onResume(){ 
     super.onResume(); 
     Log.e(TAG, "----onRESUME Called"); 

    } 

    @Override 
    protected void onPause(){ 
     super.onPause(); 
     Log.e(TAG, "----onPAUSE Called"); 

    } 

    @Override 
    protected void onStop(){ 
     super.onStop(); 
     Log.e(TAG, "----onSTOP Called"); 
    } 

    @Override 
    protected void onDestroy(){ 
     super.onDestroy(); 
     Log.e(TAG, "----onDestroy Called"); 


    } 
} 

Любая помощь действительно ценится, если вам нужна дополнительная информация о коде, я обновлю сообщение. Спасибо!

ответ

0
  • Android система может перезапустить службу, если у return START_STICKY внутри onStartCommand().

  • Он отлично работает на всех более низких версиях, чем Lollipop в Android.

  • Нет необходимости в CountDownTimer.

+0

Насколько я уже пытался, START_STIKY и START_REDELIVER_INTENT отправляются, если Служба убита во время выполнения. В первом случае я должен обрабатывать нулевой Intent, во втором - переопределить мой Intent. Проблема заключается в том, что при повторном намерении после отправки какой-либо последовательности старт-стоп-стоп-стоп эти намерения будут по-прежнему отправляться по порядку, что приведет к непрерывному запуску и остановке обработчика при каждом повторном добавлении. –

+0

@Giblin van Bauzanum: Независимо от того, причина, но если служба убита, то она перезапускается системой Android. – kevz

+0

Я пробовал с намерением redeliver. если активность закрыта, через некоторое время обработчик запускается снова. Благодаря! Но если служба отключена в настройках-> App-> InUse или залив (скажем) Clean Master, то намерение больше не будет отправлено повторно :( –

Смежные вопросы