Concurrent thread solution for uploading images using listview and gridview in android

Source: Internet
Author: User

In the QQ group and forum, someone asked how to handle the multi-thread concurrency problem when downloading images from listview. I have summarized some network resources and projects here. Hope to help those who have doubts about these aspects. (The same principle applies to listview, gridview, and viewpager ).
Three knowledge points are involved:
1. Download image resources over the Internet.
2. the asynchronous task is displayed on the UI thread.
3. Solve the Problem of multi-thread concurrency when users slide freely (this problem is the focus of this tutorial)

Download image resources over the Internet
This is very simple. Here we provide a solution:
[Java]
Static Bitmap downloadBitmap (String url ){
Final AndroidHttpClient client = AndroidHttpClient. newInstance ("Android ");
Final HttpGet getRequest = new HttpGet (url );
 
Try {
HttpResponse response = client.exe cute (getRequest );
Final int statusCode = response. getStatusLine (). getStatusCode ();
If (statusCode! = HttpStatus. SC _ OK ){
Log. w ("ImageDownloader", "Error" + statusCode + "while retrieving bitmap from" + url );
Return null;
}

Final HttpEntity entity = response. getEntity ();
If (entity! = Null ){
InputStream inputStream = null;
Try {
InputStream = entity. getContent ();
Final Bitmap bitmap = BitmapFactory. decodeStream (inputStream );
Return bitmap;
} Finally {
If (inputStream! = Null ){
InputStream. close ();
}
Entity. consumeContent ();
}
}
} Catch (Exception e ){
// Cocould provide a more explicit error message for IOException or IllegalStateException
GetRequest. abort ();
Log. w ("ImageDownloader", "Error while retrieving bitmap from" + url, e. toString ());
} Finally {
If (client! = Null ){
Client. close ();
}
}
Return null;
}
The function of downloading images over the Internet via http is very simple. I copied the image directly from other articles. If I don't know it, I can leave a message for me.


Display the image on the main thread in an asynchronous task
In the above, we have downloaded an image from the network. Next, we will display the image on the main UI thread in the asynchronous task. In the android system, android provides an asynchronous task class: AsyncTask, which provides a simple method for interaction between our child thread and the main thread.
Now let's create an ImageLoader class, which has a loadImage method to load network images and display them on the android Imageview control.
[Java]
Public class ImageLoader {
 
Public void loadImage (String url, ImageView imageView ){
BitmapDownloaderTask task = new BitmapDownloaderTask (imageView );
Task.exe cute (url );
}
}
 
}
This BitmapDownloadTask class is an AsyncTask. Its main task is to download images from the Internet and display them on the imageview. The Code is as follows:
[Java]
Class BitmapDownloaderTask extends AsyncTask <String, Void, Bitmap> {
Private String url;
Private final WeakReference <ImageView> imageViewReference;
 
Public BitmapDownloaderTask (ImageView imageView ){
ImageViewReference = new WeakReference <ImageView> (imageView );
}
 
@ Override
// Actual download method, run in the task thread
Protected Bitmap doInBackground (String... params ){
// Params comes from the execute () call: params [0] is the url.
Return downloadBitmap (params [0]);
}
 
@ Override
// Once the image is downloaded, associates it to the imageView
Protected void onPostExecute (Bitmap bitmap ){
If (isCancelled ()){
Bitmap = null;
}
 
If (imageViewReference! = Null ){
ImageView imageView = imageViewReference. get ();
If (imageView! = Null ){
ImageView. setImageBitmap (bitmap );
}
}
}
}
The doInBackground method in this BitmapDownloaderTask is run in the subthread, while onPostExecute is run in the main thread, and the result of doInBackground execution is returned to onPostExecute. For more AsyncTask related technologies and reference help documents of android (this technical point is not discussed in this chapter ).
So far, we have been able to download images over the network through asynchronous tasks and display them on imageview.

Multi-thread concurrent processing
Although we have implemented the sub-thread to download images and display them in imageview, when users slide freely in listview and other containers, N threads will be generated to download images, which we don't want to see. We hope that only one thread can download an image.
To solve this problem, we should make this imageview remember whether it is loading (or downloading) network image resources. If loading is in progress or loading is complete, I should not create another task to load images.
Now let's modify it as follows:
[Java]
Public class ImageLoader {
 
Public void loadImage (String url, ImageView imageView ){
If (cancelPotentialDownload (url, imageView )){
BitmapDownloaderTask task = new BitmapDownloaderTask (imageView );
DownloadedDrawable downloadedDrawable = new DownloadedDrawable (task );
ImageView. setImageDrawable (downloadedDrawable );
Task.exe cute (url, cookie );
}
}
}
 
}

First, we first use the cancelPotentialDownload method to determine whether the imageView has a thread that is downloading image resources for it. If a thread is downloading image resources, then determine the downloaded image resource (url) if it is the same as the current image resource, cancel the previous thread (the previous download thread is voided ). The cancelPotentialDownload method code is as follows:
[Java]
Private static boolean cancelPotentialDownload (String url, ImageView imageView ){
BitmapDownloaderTask bitmapDownloaderTask = <span style = "color: # cc0000;"> getBitmapDownloaderTask (imageView); </span>
 
If (bitmapDownloaderTask! = Null ){
String bitmapUrl = bitmapDownloaderTask. url;
If (bitmapUrl = null) | (! BitmapUrl. equals (url ))){
<Span style = "color: # ff6666;"> bitmapDownloaderTask. cancel (true); </span>
} Else {
<Span style = "color: # ff0000;"> // The same url is already being downloaded.
Return false; </span>
}
}
Return true;
}
When bitmapDownloaderTask. when cancel (true) is executed, BitmapDownloaderTask is canceled. When BitmapDownloaderTask is executed to onPostExecute, if this task is loaded to an image, it also sets this bitmap to null.
The getBitmapDownloaderTask code is as follows:
[Java]
Private static BitmapDownloaderTask getBitmapDownloaderTask (ImageView imageView ){
If (imageView! = Null ){
Drawable drawable = imageView. getDrawable ();
If (drawable instanceof DownloadedDrawable ){
DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
Return downloadedDrawable. getBitmapDownloaderTask ();
}
}
Return null;
}
DownloadedDrawable is a custom class. Its main function is to record the download task and set it to imageview. The Code is as follows:
[Java]
Static class DownloadedDrawable extends ColorDrawable {
Private final WeakReference <BitmapDownloaderTask> bitmapDownloaderTaskReference;
 
Public DownloadedDrawable (BitmapDownloaderTask bitmapDownloaderTask ){
Super (Color. BLACK );
BitmapDownloaderTaskReference =
New WeakReference <BitmapDownloaderTask> (bitmapDownloaderTask );
}
 
Public BitmapDownloaderTask getBitmapDownloaderTask (){
Return bitmapDownloaderTaskReference. get ();
}
}

Finally, let's modify BitmapDownloaderTask's onPostExecute method:
[Java]
If (imageViewReference! = Null ){
ImageView imageView = imageViewReference. get ();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask (imageView );
// Change bitmap only if this process is still associated with it
If (this = bitmapDownloaderTask ){
ImageView. setImageBitmap (bitmap );
}
}

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.