2014-11-07 3 views
0

У меня есть проблемы с пониманием 1 Thing in Population ListView, так как мой опыт говорит, что методы, которые выполняются в потоке пользовательского интерфейса, имеют самый высокий приоритет и поэтому работают намного быстрее, чем методы, выполняемые в backGround, но разница в том, что поток пользовательского интерфейса не ждет их завершения, поэтому мы Не чувствуй в нем никакой задержки.Почему мы должны использовать AsyncTask с возвратом, вместо того, чтобы работать в потоке пользовательского интерфейса?

Но когда мы с помощью AsyncTask с результатом, как это:

Class async extends AsyncTasl<Void,Void,Bitmap>{ 

@Override 
public Bitmap doInBackGround(Void...Params){ 
. 
. 
. 
    return new bitMap; 
    } 
} 

, поскольку она возвращает некоторую вещь, поэтому MainThread должен ждать его, чтобы закончить, что сводит на нет основную цель работает в фоновом режиме, поэтому я я понимаю, что-то не так, или нет никаких причин делать такие вещи в BackGround, пока они могут работать даже быстрее на тему пользовательского интерфейса?

UPDATE:.

моя точка, когда мы используем async.execute() получает()

+1

Если основной поток выполнит 'Результат результата = новый AsyncTask(). DoInBackground()' (т. Е. Вызовите метод doInBackground'), ему придется ждать результата. Но это не так. Результат приходит магически в методе 'onPostExecute'. – zapl

+0

'async.execute(). Get()' ** не называть это на поток ui **. В действительности фактически отрицается вся суть использования асинтакты. Что происходит, так это то, что ваш поток bg выполняет эту работу, в то время как поток ui сидит в ожидании (заблокирован) для потока bg, чтобы завершить работу. – njzk2

+0

thats extacly, что я имел в виду, так почему, когда я передаю свой imageView в задачу async, чтобы установить Bitmap. После того, как она закончит, позиции моей строки запутались! – Reza

ответ

0

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

Изображение этой сцены: Вам необходимо загрузить элементы списка, к которым прикреплен значок, и этот значок живет по URL-адресу и должен быть получен с помощью сетевого запроса.

Вот пример кода, который получает изображение, расположенный в URL всякий раз, когда на экране появляется элемент списка:

public View getView(int position) { 
    final URL imageURL = getURL(position); 
    final Bitmap image = getImage(imageURL); //this will take a while 
    ... 
    view.setIcon(imageIcon); 
    return view; 
} 

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

Если это все сделано в потоке пользовательского интерфейса, пользователь увидит список, который требует мучительно длительного времени для загрузки каждого элемента списка. Основной поток недостаточно умен, чтобы сократить длительные задачи на короткое время (что, если эта долговременная задача состояла в том, чтобы сохранить важные пользовательские данные во внешнем БД где-то?), Поэтому он должен позволить им полностью закончить. Также важно отметить, что поток пользовательского интерфейса мало чем отличается от любого другого потока с точки зрения системы. Это важно, потому что именно там происходит пользовательский интерфейс.

Именно поэтому наилучшая практика при написании любого приложения на любой платформе заключается в том, чтобы выгрузить длительные задачи в фоновый поток. ОС может обрабатывать переключение между потоками, что приводит к созданию пользовательского интерфейса, который очень чувствителен к действиям пользователя (например, прокручивание списка).

Как продемонстрировал ABFORCE, вы должны получать изображения с помощью AsyncTask на Android. В фоновом режиме будет сделан запрос на URL-адрес для изображения, и только когда готовое окончательное изображение будет показано на странице, будет вызван вызов в поток пользовательского интерфейса для его отображения. Пользователь увидит список, который они могут быстро пронести, и изображения будут появляться в каждом элементе списка, когда они будут извлечены. Мы не хотим удерживать пользователя от , делая что-то, поэтому мы хотим убедиться, что они могут пронести по списку так быстро, как они хотят.

UPDATE: Если вы должны были сделать новый AsyncTask(). Execute.get(), этот метод действительно блокирует поток пользовательского интерфейса, отрицая преимущества фонового потока. То, что вам может понадобиться сделать в вашем классе, который расширяет AsyncTask, содержит ссылку на представление, в котором вы хотите, чтобы ваш образ был частью (я принимаю новый AsyncTask для каждого элемента списка), а в onPostExecute задает любое поле, которое должно быть установленный на этом представлении.

Пример:

class async extends AsyncTask<Void,Void,Bitmap>{ 

    private View view; 

    @Override 
    public Bitmap doInBackGround(Void...Params) { 
     /* Here is background thread */ 
     return new Bitmap(); ----+ 
    }       | 
           | //this object will be passed here 
    @Override     V 
    public void onPostExecute(Bitmap result) { 
     /* Here is main thread */ 
     view.setIcon(result); 
    } 
} 

в другом месте ...

public View getView(int position) { 
    new async(view).execute(); 

    return view; //View will return now, and the image will populate later 
} 

Есть, очевидно, много способов сделать это, и это один с верхней части моей головы.

+0

im, пытающегося сделать это все время, но мои строки в списке смешаны, и их позиции будут неправильными, когда я передам ссылку на ImageView на асинхронную задачу, поэтому он устанавливает Bitmap в нее onPostExecute, поэтому я нет выбора, кроме использования метода get() async-задачи! – Reza

0

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

При вызове asyncTask.execute(),

  • onPreExecute (..) обратного вызова выдается на UI потоке
  • doInBackground (..) называется в фоновом потоке (если я правильно понял ваш вопрос правильно, основной поток здесь не ждет). Когда вы получаете данные с сервера (скажем) в этом методе, вы возвращаете данные, чтобы система Android вызывала onPostExecute с этими данными в потоке пользовательского интерфейса.
  • onPostExecute (..) выдается в потоке пользовательского интерфейса с помощью данные, которые вы вернули в doInBackground (..) в качестве параметра.
+0

это не всегда slike это, когда вы выполняете его с async.execute(). Get, thats, как вы заполняете listView без смешивания строк – Reza

+0

Да, вам нужно установить тег в представлении, чтобы его не смешивать происходит. – sr09

+0

, если вы имеете в виду ViewHolder, но все же :( – Reza

0

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

Class async extends AsyncTasl<Void,Void,Bitmap>{ 

    @Override 
    public Bitmap doInBackGround(Void...Params){ 
     /* Here is background thread */ 
     return new Bitmap(); ----+ 
    }       | 
           | //this object will be passed here 
    @Override     V 
    public void onPostExecute(Bitmap result){ 
     /* Here is main thread */ 
    } 
} 
+0

, как я упоминал выше, я имел в виду, когда вы вызываете async.execute(). Get, иначе элементы ListView будут смешиваться, по крайней мере, в моем случае это происходит, когда я передаю imageView в async для установки drawable – Reza

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