IntentService не срабатывает

Мое приложение синхронизирует данные с удаленной базой данных через вызовы веб-службы. Я делаю эти вызовы в IntentService, чтобы они могли работать в фоновом режиме (. Я называю это SyncService ).

Код для запуска моего IntentService выглядит так:

Intent intent = new Intent();
intent.setClass(appContext, SyncService.class);

// place additional values in intent
intent.putExtra("data_type", SyncService.ITEM_TRACKING);
intent.putExtra("user_id", intUserId);

// call SyncService
appContext.startService(intent);

Это, как правило, выглядит великолепно. Однако один из моих друзей, который также является пользователем моего приложения, часто говорит мне, что его данные не синхронизируются и не отображаются на нашем веб-сайте. Его устройство показывало симптомы, пока я был рядом. Я подключил его устройство к своему компьютеру и вот что нашел:

  • Код для запуска SyncService (т.е. :код выше )сработал.
  • У меня была точка останова внутри метода onHandleIntent моего IntentService, и она никогда не срабатывала.
  • Я проверил список запущенных служб его устройства, и SyncService был там и работал. Интересно, что он работал около 20 минут. У меня сложилось впечатление, что IntentService убил себя, когда все было не в состоянии обработать намерения.
  • Я принудительно остановил SyncService (, а не приложение ), и внезапно onHandleIntent начал получать удары снова и снова. Это было похоже на то, что все намерения были поставлены в очередь где-то на устройстве и только что были отправлены в SyncService.

У кого-нибудь есть идеи, в чем может быть проблема? Как вы думаете, это проблема с моим приложением? С Андроидом?

Опять же, я передаю сообщение Android, в котором говорится: «Запустите этот IntentService или отправьте сообщение уже запущенному IntentService». В этот момент у меня нет контроля. Сообщение никогда не попадает в IntentService. Как только я принудительно выхожу из приложения, сообщения отправляются в IntentService, и он выполняет свою работу.

ОБНОВЛЕНИЕ :Я думаю, что этот код хорош, но я положу его, так как многие из вас могут захотеть его увидеть.

Каждое намерение, которое поступает в IntentService, имеет дополнительное значение, обозначающее, какой «тип» вызова мне сделан (, то есть :я вызываю эту веб-службу или ту веб-службу. обслуживание и т. д. ). Когда Intent поступает в IntentService, я проверяю «тип» и, если в очереди уже есть Intent для этого типа, я добавляю к нему Extra под названием «skip», поэтому, когда он будет достигнут, я не t выполнить поиск (, в основном IntentService может создать множество намерений, и нет смысла вызывать этот веб-сервис, когда этот веб-сервис был вызван 20 секунд назад ). Это в основном защищает приложение от спама на веб-сайте.

Важно отметить, что ни один из этих кодов в любом случае не срабатывает (, когда проблема начинает возникать ). onStartCommand не вызывается, пока приложение не будет убито

    @Override
    public int onStartCommand (Intent intent, int flags, int startId) {
        // here be dragons
        // overriding this method and adding your own code is dangerous. i've wrapped
        // my code in a try/catch because it is essential that the super method be called
        // every time this method is entered. any errors in my code should not prevent this
        // or the app will explode.
        try {
            if (flags == 0 && intent != null && intent.hasExtra("data_type")) {
                Integer intDataType = intent.getExtras().getInt("data_type");

                    if (!mCurrentTypes.containsKey(intDataType)
                            || !mCurrentTypes.get(intDataType)) {
                        mCurrentTypes.put(intDataType, true);  // put this type in the list and move on
                    }
                    else {
                        intent.putExtra("skip", true);  // mark this Intent to be skipped
                    }
            }
        }
        catch (Exception e) {
            // Log.e("Error onStartCommand", "error: " + e);
        }

        return super.onStartCommand(intent, flags, startId);
    }


private void processIntent(Intent intent) {
        // do stuff if no "skip" Extra
        mCurrentTypes.put(intDataType, false);
    }
6
задан Andrew 2 December 2012 в 22:28
поделиться