Сервис v / s AsyncTask

Я смущен в отношении дизайна моего приложения. Мне нужно постоянно опросить сервер, чтобы получить от него новые данные. Я смущен тем, что лучше использовать опцию Async Task с фиксированным интервалом или запуском службы. Поток запускается только при запуске приложения

У вас уже есть ответы на ваш вопрос, но я думаю, что это стоит резюме …

Что вам нужно

Когда вы хотите запустить фрагмент кода, который занимает некоторое время, вы должны всегда запускать его в отдельном потоке из потока пользовательского интерфейса.

Вы можете достичь этого двумя способами:

Использование Thread :

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

Использование AsyncTask :

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

Что вам не нужно

Service

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

IntentService

Это может быть активировано внешним событием (т. BroadcastReceiver ), которое может запустить часть кода, определенную вами, даже если ваше приложение не запущено. Еще раз, исходя из ваших требований, это не то, что вы ищете.

С уважением.

Служба Android не находится в фоновом потоке.

Поэтому вы должны запустить службу, которая будет запускать ASyncTask каждый раз, когда вы хотите опросить.

Обратите внимание, что службы, как и другие объекты приложения, запускаются в основном потоке их процесса хостинга. Это означает, что если ваша служба будет делать какие-либо интенсивные работы с ЦП (например, воспроизведение MP3) или блокирование (например, сетевые), она должна создать собственный поток для выполнения этой работы. Более подробную информацию об этом можно найти в разделе «Процессы и потоки». Класс IntentService доступен как стандартная реализация Службы, которая имеет свой собственный поток, где он планирует выполнить свою работу.

Service не следует сравнивать с AsyncTask . Думаю, вы, скорее всего, подразумевали IntentService здесь – и это немного другое, чем Service , несмотря на общее имя.

Что касается периодической выборки, я буду придерживаться повторяющейся тревоги (используя AlarmManager ) и (скорее всего), используя IntentService чтобы выполнить IntentService .

Здесь вы получили основы AsyncTask и некоторые учебные пособия. И здесь вы получили основы IntentService и учебные пособия

Обратите внимание, что задания IntentService помещаются в очередь по дизайну, в то время как AsyncTasks может работать полностью паралельно. Однако имейте в виду регрессию, связанную с обработкой AsyncTask в новых API . Не так много, как обходное решение – это всего лишь несколько строк кода, однако это стоит того.

РЕДАКТИРОВАТЬ

Существует недоразумение, плавающее среди многих относительно жизненного цикла AsyncTask, связанного с жизненным циклом деятельности. Это НЕПРАВИЛЬНО . AsyncTask не зависит от Activity. Finishing Activity ничего не делает для любых AsyncTasks, если вы не очищаете их от onDestroy () своим кодом. Тем не менее, если процесс активности убивается, когда он находится в фоновом режиме, тогда AsyncTask также будет убит, так как часть всего процесса будет убита

Если вы хотите «непрерывно опросить», asyncTask не будет делать. Задача останавливается, когда приложение приостанавливается Android. Служба сама по себе не будет делать этого, как уже указывал Бланделл. Служба работает в основном потоке, и вы не хотите делать опросы в основном потоке. Есть два способа сделать это: вы создаете Службу, которая порождает собственный поток, чтобы делать то, что вы хотите, или позволяете ему планировать опросы, которые выполняются в AsyncTask или в отдельном потоке. Я стараюсь не иметь опроса в своем приложении, но если вам нужно, создавая специальный поток в вашей службе, который делает опрос наилучшим для меня.

В зависимости от того, что делает ваше приложение и что такое опрос, вы можете дать отдельному потоку более низкий приоритет, чтобы он не мешал другой обработке.

Поток запускается только при запуске приложения

Тогда AsyncTask будет самым простым решением. Периодически отправляйте данные в поток приложений, используя publishProgress() из фонового потока. Установите желаемый интервал, используя Thread.sleep() в doInBackground() . Кроме того, убедитесь, что вы запустили новую задачу в onResume() Activity и закончите эту задачу в onPause() методе Activity.

Пример:

 public class MyActivity extends Activity { private AsyncTask<Void,String,Void> mAsyncTask; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void onResume() { super.onResume(); mAsyncTask = new MyTask(); mAsyncTask.execute(); } @Override protected void onPause() { super.onPause(); if(mAsyncTask != null){ mAsyncTask.cancel(true); } } private void onServerResponse(String response){ Toast.makeText(this, "Got response !", Toast.LENGTH_SHORT).show(); } private final class MyTask extends AsyncTask<Void,String,Void>{ @Override protected Void doInBackground(Void... voids) { while (!isCancelled()){ String response = ""; //server query code here publishProgress(response); Log.i("TEST", "Response received"); //sleep for 5 sec, exit if interrupted ,likely due to cancel(true) called try{ Thread.sleep(5000); }catch (InterruptedException e){ return null; } } return null; } @Override protected void onProgressUpdate(String... values) { super.onProgressUpdate(values); if(values.length > 0){ onServerResponse(values[0]); } } } }