2

В android почему мы должны использовать asyntask и службу вместо использования нового потока() и записи необходимой функциональности фона?Почему мы должны использовать aysntask или службу вместо нового потока

Я знаю, что мы не должны запускать длительные операции, такие как загрузка файла с сервера на mainthread aka UI thread. И должен использовать асинтез или службу.

Но почему мы не создаем новый поток() {который, в конечном счете, является новым потоком, отличным от основного потока}, и записывать в этот поток обязательно длительную операцию.

Почему Google создала AsyncTask и службу, не предлагая использовать обычную новую тему() ???

заранее спасибо

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

я получить его, все дело начинается с

Do not block the UI thread 
Do not access the Android UI toolkit from outside the UI thread 

почему? 1. Как много может обрабатывать поток пользовательского интерфейса? как мы можем определить точку останова? как определяется точка ANR? мы можем отслеживать?
2. Когда компонент службы обрабатывает длительные операции, почему не может обрабатываться компонент компонента активности?

Помните, что если вы используете службу, он по-прежнему работает в главном потоке вашего приложения по умолчанию, так что вы все равно должны создать новый поток внутри службы, если он выполняет интенсивные или блокирующие операции http://developer.android.com/guide/components/services.html выше заявление из документации по android.

3.Почему, возможно, начало службы в новой теме, если мы так обеспокоены основной нитью? не поймите меня неправильно в вопросе 3, я пытаюсь понять преимущество запуска службы в основной теме. по умолчанию.

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

+2

Это делает все намного проще. – hichris123

+2

сервис абсолютно не связан. он не может заменить или заменить нить. они выполняют совершенно разные вещи. AsyncTask является оберткой вокруг Thread + Scheduler + runOnUiThread. – njzk2

+0

Лучше всего прочитайте ** [Процессы и потоки] (http://developer.android.com/guide/components/processes-and-threads.html) ** в Android, которые должны ответить на ваш вопрос. –

ответ

8

Хорошо, давайте посмотрим, как выполнить простую задачу с помощью Thread.

Первым шагом является создание потока с использованием Runnable.Что-то вроде этого:

private void fetchResultsAsync() { 
    Runnable runner = new Runnable() { 

     @Override 
     public void run() { 
      List<String> results = fetchResultsFromWebServer(); 
     } 
    }; 
    new Thread(runner).run(); 
} 

Дело в том, что мы должны показать результаты, так что бы быть на самом деле больше, как это:

private void fetchResultsAsync() { 
    Runnable runner = new Runnable() { 

     @Override 
     public void run() { 
      List<String> results = fetchResultsFromWebServer(); 
      workFinished(results); 
     } 
    }; 
    new Thread(runner).run(); 
} 
private void workFinished(List<String> results) { 
    // show the results on the UI 
} 

Он выглядит хорошо, но есть одна проблема; метод обратного вызова (workFinished) должен обновить пользовательский интерфейс. Если мы сделаем это из любого основного потока, возникнут большие проблемы. Нам нужен потокобезопасный способ вызова этого метода, для которого предназначены обработчики. Давайте также бросим метод обновления нашего прогресса, который очень распространен. Код будет выглядеть следующим образом:

private final Handler myHandler = new Handler(); 
private void fetchResultsAsync() { 
    Runnable runner = new Runnable() { 

     @Override 
     public void run() { 
      List<String> results = fetchResultsFromWebServer(); 
      workFinished(results); 
     } 
    }; 
    new Thread(runner).run(); 
} 
private void showProgress(int result) { 
    myHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      // update a progress bar here 
     } 
    }); 
} 
private void workFinished(final List<String> results) { 
    myHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      // show the results on the UI 
     } 
    }); 
} 

Сравните это с реализацией с использованием AsyncTask:

private void fetchWithTask() { 
    new AsyncTask<Void, Integer, List<String>>() { 

     @Override 
     protected List<String> doInBackground(Void... params) { 
      return fetchResultsFromWebServer(); 
     } 

     @Override 
     protected void onPostExecute(List<String> strings) { 
      // show the results on the UI 
     } 

     @Override 
     protected void onProgressUpdate(Integer... values) { 
      // update a progress bar here 
     } 
    }.execute(); 
} 

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

Теперь представьте, что у вас есть несколько различных типов небольших фоновых задач, которые необходимо выполнить. Было бы очень легко вызвать неправильный метод showProgress или workFinished из неправильного фона Thread, потому что вы должны объединить все эти части вместе.

Существует также очень неприятная ошибка, скрывающаяся при использовании конструктора по умолчанию обработчика. Если содержащемуся классу в первую очередь ссылается поток не-UI во время выполнения, обработчик будет принадлежать этому потоку. AsyncTask скрывает, всегда делает вещи в правильной теме. Это трудно поймать!

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

+0

hey @Krylez спасибо за объяснение. Я понимаю всю концепцию Asynctask. спасибо, хотя за подробное объяснение. Я попытался проголосовать, но мне нужна репутация в 15 минут. – user109245

1

«вместо того, чтобы использовать новый поток() и написать необходимую функциональность фона?»

Зачем переписывать функциональность фона? AsyncTask делает это за вас. Как упоминалось в njk2, сервис не является действительно хорошим сравнением, хотя IntentService автоматически создает новый поток для вас в onHandleIntent().

Редактировать: Чтобы ответить на ваши другие вопросы, блокируя поток пользовательского интерфейса, будет блокировано все взаимодействие с пользователем, и приложение будет выглядеть «замороженным». Определенно не то, что мы хотим делать вообще.

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