Android asynchronous loading full parsing using multithreading

Source: Internet
Author: User

Android asynchronous loading full parsing using multithreading
Asynchronous loading uses multiple threads for the first time. asynchronous and asynchronous loading means multi-task processing, that is, multi-thread execution. Multiple Threads may cause various problems. Let's look at them step by step. First, let's create a class -- ImageLoaderWithoutCaches. From the naming, we can also see that this class implements image loading without caching, not to mention, create another method -- showImageByThread to load the image through multiple threads:

/** * 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 = (Bitmap) 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 method, we have enabled a thread and used the image download method we mentioned earlier in the new thread to download images. Because it is no longer the main thread, so we can do what we want. After the download, the Handler object is used to notify the Handler who has waited for a lifetime in the main thread. After receiving the message, the Handler manipulated the UI and modified the imageView image. OK, run.

Lying grass, pitfall me, some old pictures flash, some pictures do not move, slide and keep changing, what is this ghost. This is certainly not the result we want to see. But why? First, we need to understand the Recycler mechanism of ListView.
Recycler mechanism of ListView
public View getView(int position, View convertView, ViewGroup parent)

This is the getView () method in ListView, And the convertView parameter is our No. 1 suspect. Suppose we have 100 data records, but only 10 are displayed on the page. Android is not an idiot yet. During initial creation, the value is displayed and convertView is created. When you slide, for example, sliding up an Item, Item1 is hidden and Item11 is displayed from below, at this time, if Android creates another convertView, it will be scolded because it first needs to recycle Item1 and then create Item11. Is it interesting? To solve this problem, Android provides a Recycler mechanism in ListView. To put it bluntly, it creates an Item buffer pool. When Item1 disappears, it is not recycled, instead, it enters the buffer pool and becomes a second-hand product. When Item11 is displayed, it will retrieve Item1 from the buffer pool and erase Item1 data to continue using it, item11 and Item1 display the same content, because they have the same address in the memory and are essentially an Item. However, Item1 is invisible at this time, so it has nothing to do with Item11. When it is displayed again, write the correct data again. Here I have stolen a picture on the Internet to help you understand the concept of second-hand goods:
Of course, if it is not an asynchronous operation, nothing happens, because the Android UI is single-threaded, Or you reuse convertView, but every time you create a new one, it's okay, of course you won't do this either. It's too Low. But asynchronous mode is different. For example, if we download images here, each image has its own temper and the download speed is different. When the ListView is initially displayed, the downloading of the Item1 image is too slow. When you slide up and show Item11, the figure of Item11 is shown as flying, and the figure of Item11 is displayed as soon as possible. OK, the figure of Item11 is displayed as soon as possible, the slow graph in Item1 is also ready. It looks for Item1, but it does not know that Item1 has changed to Item11 at this time. It also sets an image for others, isn't that messy? OK. How can we solve this problem? The problem now is that the downloaded image is like a hibernation person who has been sleeping for 20 years and finds that he was not the old man, but its memory is still 20 years ago. Therefore, we need to establish a sign to let the hibernator come back and see whether the current uncle is your previous uncle. In Android, we can easily use tags to identify the View. When Item1 is displayed, the tag is set to url1, And then it downloads url1. After sliding, when Item11 is displayed, the tag is changed to url11 and the diagram of url11 is downloaded. When the image of url1 is downloaded, you only need to check whether the tag is url1, and then you will know whether the uncle is still the uncle. If not, it will not be displayed. This will avoid the problem of misplacement. Of course, there is still a pitfall in the previous example. I will not bury everyone. After the download is complete, I will use handler to notify the UI thread to modify the ImageView. However, at this time, the ImageView In the parameter may not have a one-to-one relationship with the image passed at this time, and the display is definitely incorrect. Therefore, we also need to pair the url with the corresponding ImageView, the simplest way is to use an object for storage. After the multi-thread asynchronous download solution tries for the first time and analyzes the cause of failure, we fill in the above two pitfalls. 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 still uses Handler. There is no other choice. First, we download the image and save the image and ImageView through an object. After Handler obtains the object, it determines whether to load by judging whether the current tag corresponds to the url. Here we have used the following mentioned in the opening part of Asynchronous Full parsing for Android:
viewHolder.imageView.setTag(url);

This is useful.
Finally, modify the code in the 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;}

In getView, the image is asynchronously loaded.
At this time, we will run the program again, the effect is as follows:

OK.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.