Asynchronous onboarding using multithreaded first attemptAsynchronous, asynchronous, in fact, the truth is multitasking. That is, multithreaded execution. Multithreading then there will be a variety of problems, we step by step to see. First of all. We create a class--imageloaderwithoutcaches, from the name. As you can see, this class, we implement the image loading without the cache, not much, we create a method--showimagebythread, load the image through a multi-thread:
/** * Using Thread * @param imageView * @param url */public void showimagebythread (Final ImageView ImageView, final String URL) { Mhandler = new Handler () { @Override public void Handlemessage (Message msg) { Bitmap Bitmap = (Bit map) Msg.obj; Imageview.setimagebitmap (bitmap); } }; New Thread () { @Override public void Run () { Bitmap Bitmap = getbitmapfromurl (URL); Message message = Message.obtain (); Message.obj = bitmap; Mhandler.sendmessage (message); } }. Start ();}
In this way, we open a thread and use the new thread to download the image we said earlier, because this is not the main thread, so we want to how to next. Sky high Emperor far.After downloading, through the handler object to tell the message in the main thread for a lifetime of handler, after receiving the message, handler manipulate the UI, change the ImageView image. Ok. Run up.
watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvzwnsaxbzzxh5cw==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/center "/>
Lying grass, pit me, some pictures of old flashes, and some are not moving, sliding a slippery still change, this is what ghosts.
This is certainly not the result we want to see. But why is that? Let's start with the analysis. First, we need to understand the recycler mechanism of the next ListView.
The recycler mechanism of the ListView
Public View GetView (int position, view Convertview, ViewGroup parent)
Thisis the GetView () method in the ListView, and the number of Convertview is our number one suspect. If we have 100 data, only 10 can be displayed on the page. Android doesn't have to be idiots to create it all first. At the time of initial creation, how much is displayed and how much Convertview is created when you swipe. For example, swipe up one item. Then Item1 will be hidden. ITEM11 will come out from below, then, if Android again to create a convertview, then it will be scolded dead, because it first to reclaim Item1, and then to create ITEM11. Is it interesting?To solve such a problem, Android provides a recycler mechanism in the ListView, which plainly creates a buffer pool of item when Item1 disappears. It has not been recycled. Instead, it enters the buffer pool. Became secondhand when the ITEM11 was displayed. It will remove the Item1 from the buffer pool. Wipe the ITEM1 data and continue to use it. So this time, ITEM11 and ITEM1 will show the same content. Because their addresses in memory are the same, they are essentially an item. But at this time, the Item1 was out of sight. So what it shows, it doesn't matter to ITEM11.
When it shows up again, it's good to write the correct data again. here on the internet to steal a picture, to help you understand such a concept of picking up secondhand:
Of course, assuming it's not an asynchronous operation, there's no fart, because the Android UI is single-threaded, or you re-convertview but new one every time, that's fine. Of course you wouldn't do that. It's too low.
But async is not the same, take us here to download pictures, every picture has its own temper. Everyone downloads the speed is not the same, when the initial display ListView. Item1 picture Download too slow, when you slide up, show Item11, ITEM11 figure shows the fly, immediately under the good. The diagram of the OK,ITEM11 shows well, but immediately. Item1 under the slow figure also under good, it went to find Item1, but it did not know this time Item1 has become Item11. It also goes to set images for others. Isn't that a mess? OK, know the reason, how can we solve it? The problem now is that the downloaded image is like a hibernating person who sleeps for 20 years. Found that his uncle is not the old man, but its memory still stopped 20 years ago.
Therefore, we need to establish a sign to let hibernate friends come back to see clearly, now this big uncle is not the one you once. in Android. We can easily use tag to identify the view. When the Item1 is displayed, the tag is set to URL1. Then it went to download URL1, when the slide, the display ITEM11, this time tag was changed to Url11, download Url11 diagram. And when the picture of URL1 downloaded well, come back just to see if tag is url1 know ye or not that big uncle, assuming not. It doesn't show up, so you can avoid the problem of dislocation. of course. The previous example in the other pit, I will not bury everyone, after completing the download. Change ImageView by handler the picture to the UI thread, but this time. The ImageView in the number of references may not be the same as the one by one corresponding relationship, the display is definitely wrong, so we also need to let the URL and the corresponding ImageView to be paired, the simplest way is to use an object to save. Multi-threaded asynchronous Download Positive solution after the initial attempt and analysis of the reason for the failure. We fill up the top two pits, and the modified method is as follows:
/** * Using Thread * @param imageView * @param url */public void showimagebythread (Final ImageView ImageView, final String URL) { Mhandler = new Handler () { @Override public void Handlemessage (Message msg) { Imgholder holder = ( Imgholder) Msg.obj; if (Holder.imageView.getTag (). Equals (Holder.url)) { holder.imageView.setImageBitmap (holder.bitmap);}} } ; New Thread () { @Override public void Run () { Bitmap Bitmap = getbitmapfromurl (URL); Message message = Message.obtain (); Message.obj = new Imgholder (ImageView, bitmap, url); Mhandler.sendmessage (message); } }. Start ();}
Private class Imgholder {public Bitmap Bitmap; Public ImageView ImageView; public String URL; Public Imgholder (ImageView IV, Bitmap bm,string URL) { this.imageview = IV; This.bitmap = BM; This.url = URL;} }
The modified method, is still using handler, this has no other choice, first we download the image, and then the image and ImageView through an object to match the save. After handler gets the object, it decides whether to load it by inferring whether the current tag and URL are appropriate.
Here's what we've mentioned in the beginning of the full resolution of Android Async loading:
ViewHolder.imageView.setTag (URL);
It's going to come in handy.
At last. Change the code in adapter:
@Overridepublic view GetView (int position, view Convertview, ViewGroup parent) { String url = mdata.get (position);
viewholder viewholder = null; if (Convertview = = null) { Viewholder = new Viewholder (); Convertview = minflater.inflate (R.layout.listview_item, null); Viewholder.imageview = (ImageView) Convertview.findviewbyid (r.id.iv_lv_item); Convertview.settag (Viewholder); } else { Viewholder = (viewholder) convertview.gettag (); } ViewHolder.imageView.setTag (URL); ViewHolder.imageView.setImageResource (r.drawable.ic_launcher); Mimageloader.showimagebythread (Viewholder.imageview, url); return Convertview;}
When GetView, asynchronously loads the picture.
At this point, we will execute the program again, such as the following:
OK, it can be displayed normally.
My GitHub
My video MU-class network
Android asynchronous load full parsing using multithreading