Handle Concurrency for GridView when used in conjunction with AsyncTask
I'm reading chapter processing bitmaps off the UI thread in Android training. In this chapter, the author talks about handling concurrency for GridView when used in conjunction with AsyncTask:
Common view components such as ListView and GridView introduce another issue when used in conjunction with the AsyncTask as demonstrated in the previous section. In order to be efficient with memory, these components recycle child views as the user scrolls. If each child view triggers an AsyncTask, there is no guarantee that when it completes, the associated view has not already been recycled for use in another child view. Furthermore, there is no guarantee that the order in which asynchronous tasks are started is the order that they complete.
For the above paragraph, I have two questions:
(1) What's the child view of the GridView? Take the following figure as an example, is every grid a child view?
(2) I'm confused by "If each child view triggers an AsyncTask, there is no guarantee that when it completes, the associated view has not already been recycled for use in another child view." Can anyone explains more detail? For example, grid[1,1] triggers an AsyncTask, when the AsyncTask finishes, why there may incur a problem?
Yes, Each grid item is a Child View.
The main purpose of an AsyncTask is process long-running jobs off the main thread so the UI doesn't hang. Internally, an AsyncTask uses a ThreadPoolExecutor with a fixed number of threads to manage tasks. So even if you fire off twenty AsyncTasks, only a few of them will be executing at a time. At the same time, since each AsyncTask runs in it's own thread, it might finish at any time depending on how the system decides to schedule your thread. So there really is no guarantee that the tasks will finish in the same order.
When you process images off the main thread, you also need to consider the following scenario.
In AdapterViews, we recycle the child views so that we don't need to initialize new Views every time a View is scrolled on screen. So what will happen in this case is that a Child View will trigger an AsyncTask to fetch the image when it appears on screen.
But before the image is fetched, the user continues scrolling and the view scrolls off the screen and appears again on the other side(because we are recycling the views). Now, it triggers another AsyncTask to fetch the image it is supposed to display. At the same time, the earlier AsyncTask associated with this view completes and sets the Image for this View, even if it isn't the right position for the image.