Android Asynchronous loading Picture Analysis summary _android

Source: Internet
Author: User

The study of Android loading images asynchronously from the network is summarized as follows:
(1) Since the Android UI update supports a single threading principle, fetching data from the network and updating it to the interface may first be thought of in order not to block the main thread.

New handler object in main thread, loading image method as follows

Copy Code code as follows:

private void LoadImage (final String URL, final int id) {
Handler.post (New Runnable () {
public void Run () {
Drawable drawable = null;
try {
drawable = drawable.createfromstream (new URL (URL). OpenStream (), "image.png");
catch (IOException e) {
}
((ImageView) LazyLoadImageActivity.this.findViewById (ID)). setimagedrawable (drawable);
}
});
}

The disadvantage of the above method is obvious, tested, if you want to load multiple pictures, this does not achieve asynchronous loading, but wait until all the pictures are loaded to display together, because they are running in a thread.

Then, we can simply improve, to change the handler+runnable mode to Handler+thread+message mode can not be implemented simultaneously to open multiple threads?
(2) New handler object in main thread, the code is as follows:
Copy Code code as follows:

Final Handler handler2=new Handler () {
@Override
public void Handlemessage (msg) {
((ImageView) LazyLoadImageActivity.this.findViewById (MSG.ARG1)). Setimagedrawable ((drawable) msg.obj);
}
};

The corresponding loading image code is as follows:
Copy Code code as follows:

Implement multithreading asynchronous loading with Handler+thread mode
private void LoadImage2 (final String URL, final int id) {
Thread thread = new Thread () {
@Override
public void Run () {
Drawable drawable = null;
try {
drawable = drawable.createfromstream (new URL (URL). OpenStream (), "image.png");
catch (IOException e) {
}

Message message= handler2.obtainmessage ();
MESSAGE.ARG1 = ID;
Message.obj = drawable;
Handler2.sendmessage (message);
}
};
Thread.Start ();
thread = NULL;
}

This makes the asynchronous load simple. Think about it, you can also optimize, such as the introduction of the thread pool, the introduction of caching, and so on, we first introduced the thread pool.
(3) Introduce the Executorservice interface, so the code can be optimized as follows:
Add in main thread: private executorservice Executorservice = Executors.newfixedthreadpool (5);
The corresponding load image method changes as follows:
Copy Code code as follows:

Introducing a thread pool to manage multithreading
private void LoadImage3 (final String URL, final int id) {
Executorservice.submit (New Runnable () {
public void Run () {
try {
Final drawable drawable = drawable.createfromstream (new URL (URL). OpenStream (), "image.png");
Handler.post (New Runnable () {

public void Run () {
((ImageView) LazyLoadImageActivity.this.findViewById (ID)). setimagedrawable (drawable);
}
});
catch (Exception e) {
throw new RuntimeException (e);
}
}
});
}

4) in order to make it more convenient to use we can encapsulate an asynchronous loading image method to a class, exposing only one method to the outside, taking into account the efficiency problem we can introduce a memory caching mechanism, the practice is to create a hashmap, its keys (key) to load the image URL, The value is the image object drawable. Let's take a look at our encapsulated class
Copy Code code as follows:

public class AsyncImageLoader3 {
To speed up, open the cache in memory (mostly for repeated pictures, or the same image to be accessed multiple times, such as scrolling back and forth during ListView)
Public map<string, softreference<drawable>> imagecache = new hashmap<string, softreference<drawable >> ();
Private Executorservice Executorservice = Executors.newfixedthreadpool (5); Fixed five threads to perform a task
Private final Handler handler=new Handler ();

/**
*
* @param imageUrl image URL address
* @param callback Callback interface
* <a href= "http://www.eoeandroid.com/home.php?mod=space&uid=7300\" "target=" \ "_blank\" "> @return </a > returns cached images in memory, first load returns null
*/
Public drawable loaddrawable (final String imageUrl, final Imagecallback callback) {
If the cache is over, the data is fetched from the cache
if (Imagecache.containskey (IMAGEURL)) {
softreference<drawable> softreference = Imagecache.get (IMAGEURL);
if (softreference.get ()!= null) {
return Softreference.get ();
}
}
There is no image in the cache, the data is removed from the network and the extracted data is cached in memory
Executorservice.submit (New Runnable () {
public void Run () {
try {
Final drawable drawable = Drawable.createfromstream (new URL (IMAGEURL). OpenStream (), "image.png");

Imagecache.put (IMAGEURL, New softreference<drawable> (drawable));

Handler.post (New Runnable () {
public void Run () {
Callback.imageloaded (drawable);
}
});
catch (Exception e) {
throw new RuntimeException (e);
}
}
});
return null;
}
Methods of fetching data from the network
Protected drawable Loadimagefromurl (String imageUrl) {
try {
Return Drawable.createfromstream (New URL (IMAGEURL). OpenStream (), "image.png");
catch (Exception e) {
throw new RuntimeException (e);
}
}
A callback interface that is open to the outside world
Public interface Imagecallback {
Note This method is used to set the image resource of the target object
public void imageloaded (drawable imagedrawable);
}
}

It is much more convenient to use it after the encapsulation is good. In the main thread to first introduce the AsyncImageLoader3 object, and then directly call its Loaddrawable method, it is necessary to note that the Imagecallback interface imageloaded method is the only way to load the graph Like set to target ImageView or its associated components.

calling code on the main thread:
Instantiate object First private AsyncImageLoader3 AsyncImageLoader3 = new AsyncImageLoader3 ();
To invoke the asynchronous Load method:
Copy Code code as follows:

Introduces the thread pool, introduces the memory caching feature, encapsulates the interface for external calls, and simplifies the calling process
private void LoadImage4 (final String URL, final int id) {
If cached, the image is removed from the cache and the method in the Imagecallback interface is not executed
drawable cacheimage = asyncimageloader.loaddrawable (url,new asyncimageloader.imagecallback () {
See implementation: If the URL is loaded the first time, the following method executes
public void imageloaded (drawable imagedrawable) {
((ImageView) Findviewbyid (ID)). setimagedrawable (imagedrawable);
}
});
if (cacheimage!=null) {
((ImageView) Findviewbyid (ID)). setimagedrawable (Cacheimage);
}
}

5 in the same way, the following also gives the use of thread+handler+messagequeue+ memory cache code, the principle of the same (4), just the thread pool changed to Thread+handler+messagequeue mode. The code is as follows:
Copy Code code as follows:

public class Asyncimageloader {
In order to speed up, add the cache (mainly used to repeat the picture more often, or the same picture to be accessed multiple times, such as when ListView rolling back and forth)
Private map<string, softreference<drawable>> Imagecache = new hashmap<string, softreference< Drawable>> ();

/**
*
* @param imageUrl image URL address
* @param callback Callback interface
* @return Returns the cached image in memory and returns null for the first load
*/
Public drawable loaddrawable (final String imageUrl, final Imagecallback callback) {
If the cache is over, the data is fetched from the cache
if (Imagecache.containskey (IMAGEURL)) {
softreference<drawable> softreference = Imagecache.get (IMAGEURL);
if (softreference.get ()!= null) {
return Softreference.get ();
}
}

Final Handler Handler = new Handler () {
@Override
public void Handlemessage (msg) {
Callback.imageloaded ((drawable) msg.obj);
}
};
New Thread () {
public void Run () {
drawable drawable = Loadimagefromurl (IMAGEURL);
Imagecache.put (IMAGEURL, New softreference<drawable> (drawable));
Handler.sendmessage (handler.obtainmessage (0, drawable));

}

}.start ();
/*
The code below is an alternative method of handler
*/
New Asynctask () {
@Override
Protected drawable Doinbackground (Object ... objects) {
drawable drawable = Loadimagefromurl (IMAGEURL);
Imagecache.put (IMAGEURL, New softreference<drawable> (drawable));
return drawable;
// }
//
@Override
protected void OnPostExecute (Object o) {
Callback.imageloaded ((drawable) o);
// }
}.execute ();
return null;
}

Protected drawable Loadimagefromurl (String imageUrl) {
try {
Return Drawable.createfromstream (New URL (IMAGEURL). OpenStream (), "src");
catch (Exception e) {
throw new RuntimeException (e);
}
}
A callback interface that is open to the outside world
Public interface Imagecallback {
public void imageloaded (drawable imagedrawable);
}
}

At this point, the asynchronous loading is done, and the code given below is the complete code for the test:
Copy Code code as follows:

Package com.bshark.supertelphone.activity;

Import android.app.Activity;
Import android.graphics.drawable.Drawable;
Import Android.os.Bundle;
Import Android.os.Handler;
Import Android.os.Message;
Import Android.widget.ImageView;
Import COM.BSHARK.SUPERTELPHONE.R;
Import Com.bshark.supertelphone.ui.adapter.util.AsyncImageLoader;
Import Com.bshark.supertelphone.ui.adapter.util.AsyncImageLoader3;

Import java.io.IOException;
Import Java.net.URL;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;

public class Lazyloadimageactivity extends activity {
Final Handler handler=new Handler ();
Final Handler handler2=new Handler () {
@Override
public void Handlemessage (msg) {
((ImageView) LazyLoadImageActivity.this.findViewById (MSG.ARG1)). Setimagedrawable ((drawable) msg.obj);
}
};
Private Executorservice Executorservice = Executors.newfixedthreadpool (5); Fixed five threads to perform a task
Private Asyncimageloader Asyncimageloader = new Asyncimageloader ();
Private AsyncImageLoader3 AsyncImageLoader3 = new AsyncImageLoader3 ();

@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.main);

LoadImage ("Yun_qi_img/logo_new.gif", r.id.image1);
LoadImage ("Yun_qi_img/baidu_logo.gif", r.id.image2);
LoadImage ("Yun_qi_img/logo.gif", R.id.image3);
LoadImage ("Yun_qi_img/baidu_logo.gif", r.id.image4);
LoadImage ("Yun_qi_img/logo.gif", r.id.image5);

LoadImage2 ("Yun_qi_img/logo_new.gif", r.id.image1);
LoadImage2 ("Yun_qi_img/baidu_logo.gif", r.id.image2);
LoadImage2 ("Yun_qi_img/logo.gif", R.id.image3);
LoadImage2 ("Yun_qi_img/baidu_logo.gif", r.id.image4);
LoadImage2 ("Yun_qi_img/logo.gif", r.id.image5);
LoadImage3 ("Yun_qi_img/logo_new.gif", r.id.image1);
LoadImage3 ("Yun_qi_img/baidu_logo.gif", r.id.image2);
LoadImage3 ("Yun_qi_img/logo.gif", R.id.image3);
LoadImage3 ("Yun_qi_img/baidu_logo.gif", r.id.image4);
LoadImage3 ("Yun_qi_img/logo.gif", r.id.image5);

LoadImage4 ("Yun_qi_img/logo_new.gif", r.id.image1);
LoadImage4 ("Yun_qi_img/baidu_logo.gif", r.id.image2);
LoadImage4 ("Yun_qi_img/logo.gif", R.id.image3);
LoadImage4 ("Yun_qi_img/baidu_logo.gif", r.id.image4);
LoadImage4 ("Yun_qi_img/logo.gif", r.id.image5);

LoadImage5 ("Yun_qi_img/logo_new.gif", r.id.image1);
Network latency simulated to test caching
Systemclock.sleep (2000);
LoadImage5 ("Yun_qi_img/baidu_logo.gif", r.id.image2);
Systemclock.sleep (2000);
LoadImage5 ("Yun_qi_img/logo.gif", R.id.image3);
Systemclock.sleep (2000);
LoadImage5 ("Yun_qi_img/baidu_logo.gif", r.id.image4);
Systemclock.sleep (2000);
LoadImage5 ("Yun_qi_img/logo.gif", r.id.image5);
Systemclock.sleep (2000);
LoadImage5 ("Yun_qi_img/baidu_logo.gif", r.id.image4);
}

@Override
protected void OnDestroy () {
Executorservice.shutdown ();
Super.ondestroy ();
}
Basic principles of line Chengga image loading
private void LoadImage (final String URL, final int id) {
Handler.post (New Runnable () {
public void Run () {
Drawable drawable = null;
try {
drawable = drawable.createfromstream (new URL (URL). OpenStream (), "image.png");
catch (IOException e) {
}
((ImageView) LazyLoadImageActivity.this.findViewById (ID)). setimagedrawable (drawable);
}
});
}
Implement multithreading asynchronous loading with Handler+thread mode
private void LoadImage2 (final String URL, final int id) {
Thread thread = new Thread () {
@Override
public void Run () {
Drawable drawable = null;
try {
drawable = drawable.createfromstream (new URL (URL). OpenStream (), "image.png");
catch (IOException e) {
}

Message message= handler2.obtainmessage ();
MESSAGE.ARG1 = ID;
Message.obj = drawable;
Handler2.sendmessage (message);
}
};
Thread.Start ();
thread = NULL;
}
Introducing a thread pool to manage multithreading
private void LoadImage3 (final String URL, final int id) {
Executorservice.submit (New Runnable () {
public void Run () {
try {
Final drawable drawable = drawable.createfromstream (new URL (URL). OpenStream (), "image.png");
Handler.post (New Runnable () {

public void Run () {
((ImageView) LazyLoadImageActivity.this.findViewById (ID)). setimagedrawable (drawable);
}
});
catch (Exception e) {
throw new RuntimeException (e);
}
}
});
}
Introduces the thread pool, introduces the memory caching feature, encapsulates the interface for external calls, and simplifies the calling process
private void LoadImage4 (final String URL, final int id) {
If cached, the image is removed from the cache and the method in the Imagecallback interface is not executed
drawable cacheimage = asyncimageloader.loaddrawable (url,new asyncimageloader.imagecallback () {
See implementation: If the URL is loaded the first time, the following method executes
public void imageloaded (drawable imagedrawable) {
((ImageView) Findviewbyid (ID)). setimagedrawable (imagedrawable);
}
});
if (cacheimage!=null) {
((ImageView) Findviewbyid (ID)). setimagedrawable (Cacheimage);
}
}

External interface with handler+thread+ package
private void LoadImage5 (final String URL, final int id) {
If cached, the image is removed from the cache and the method in the Imagecallback interface is not executed
drawable cacheimage = asyncimageloader3.loaddrawable (url,new asyncimageloader3.imagecallback () {
See implementation: If the URL is loaded the first time, the following method executes
public void imageloaded (drawable imagedrawable) {
((ImageView) Findviewbyid (ID)). setimagedrawable (imagedrawable);
}
});
if (cacheimage!=null) {
((ImageView) Findviewbyid (ID)). setimagedrawable (Cacheimage);
}
}


}

The XML file is roughly as follows:
Copy Code code as follows:

<span style= "font-size:18px" ><STRONG>< XML version= "1.0" encoding= "Utf-8"?>

< LinearLayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Fill_parent"
android:orientation= "Vertical"
android:layout_height= "Fill_parent" >
<imageview android:id= "@+id/image1" android:layout_height= "wrap_content" android:layout_width= "Fill_parent" ></ImageView>
<imageview android:id= "@+id/image2" android:layout_height= "wrap_content" android:layout_width= "Fill_parent" ></ImageView>
<imageview android:id= "@+id/image3" android:layout_height= "wrap_content" android:layout_width= "Fill_parent" ></ImageView>
<imageview android:id= "@+id/image5" android:layout_height= "wrap_content" android:layout_width= "Fill_parent" ></ImageView>
<imageview android:id= "@+id/image4" android:layout_height= "wrap_content" android:layout_width= "Fill_parent" ></ImageView>
</linearlayout></strong></span>

Related Article

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.