Android Long-Service Создайте ветку bg, и я не знаю, что происходит - PullRequest
1 голос
/ 23 августа 2011

В основном я разрабатываю RSS-канал для Android, и я хочу иметь службу обновлений, которая для каждого источника получает каналы в определенное время.

Представьте себе:

Источник1 -5 минут Source2 - 10 минут Source3 - 10 минут

Я строю дифференциальный список, чтобы использовать только один поток, который выполняет запросы на обновление.Структура данных остается такой:

Source1 (следующий сон - 5), Source2 (следующий сон - 0, Source 3 (следующий сон 5) .. и т. Д. *

Что я делаюя всегда добавляю в список провайдеров (который содержит идентификатор и URL), а когда сон равен! = 0, я заказываю обновление (которое использует асинхронную задачу, я передаю список провайдеров для обновления, и асинктивная задача выполняет работудля меня это ... перейти в интернет, проанализировать содержимое и обновить базу данных)

, но существует один рабочий поток, который спит только для того, чтобы собрать группу поставщиков и отправить их в AsyncTask для обновления.

В чем проблема .. Сначала поток не спит в течение определенного времени, поток должен спать 10 минут, я сделал метод для преобразования минут в мили, то есть:

private static int MinutesToMilis(int minutes) { return minutes * 1000 * 60;    }

Я использую alogcat, виджет на моем телефоне, и поток спит около 25 минут (WTF): |

Еще одна вещь, которую я проверил, это то, что, когда телефон заряжается, служба работает нормально ...

Вот код:

worker = new Thread(new Runnable()
    {
        @Override
        public void run() 
        {
            Provider[] enabledProviders = feedService.getAllProvidersEnabledData();     

            // Build a differential list from enabledProviders
            DifList<Provider> list = getListForProviders(enabledProviders);     

            //
            // Code starts here
            int sleep;              
            DifNode<Provider> header = list.getFirst();

            sleep = header.getInitial();
            LinkedList<Provider> data = new LinkedList<Provider>();
            Log.d(TAG, String.format("Worker thread started @ %s", now()));

            try
            {
                for(int idx = 0 ;   true    ; list.reorderFirst(), header = list.getFirst(), idx++)
                {
                    Log.d(TAG, String.format("Iteration %s with sleep %s", idx, sleep));

                    if(sleep > 0) {
                        Log.d(TAG, String.format("Next download in %s minutes", sleep));

                        // Suspend worker thread for sleep time
                        Thread.sleep(MinutesToMilis(sleep));

                        Log.d(TAG, "Worker thread waked up from sleep");
                    }

                    // Add to data
                    data.add(header.getKey());

                    // Set next sleep time
                    sleep = header.getDifference();                     


                    if(sleep != 0)
                    {
                        Log.d(TAG, "Worker preparing for update..");
                        //
                        // If difference to next is not 0 we dump data to async task
                        for(Provider p : data){
                            Log.d(TAG, String.format("Starting update %s @ %s", p.Name, now()));
                        }

                        Provider[] arrayData = new Provider[data.size()];
                        data.toArray(arrayData);

                        data.clear();
                        new UpdateBundleOfFeedsTask().execute(arrayData);
                    }


                }
            }       
            catch(InterruptedException ex)
            {
                Log.d(TAG, String.format("Worker thread was interrupted @ %s", now()));
                isRunning = false;
            }

            Log.d(TAG, String.format("Worker thread exit @ %s", now()));
        }
    });

1 Ответ

1 голос
/ 23 августа 2011

Вы действительно не должны делать это таким образом, то есть иметь поток, который никогда не умирает.Я настоятельно рекомендую вам взглянуть на сигналы тревоги: http://developer.android.com/reference/android/app/AlarmManager.html

Хороший способ сделать это:

  • установить повторяющийся сигнал тревоги, возможно, один с другим pendingIntent длякаждый клиент, хотя в вашем случае кажется, что это слишком часто, чтобы делать это каждые 5-10 минут только для чтения некоторого RSS.
  • реализует широковещательный приемник, который прослушивает ожидающие намерения, установленные вашим сигналом тревоги.
  • из приемника вещания, запустите службу, которая запускает рабочий поток для чтения из сети и сохранения в БД.
...