My favorites | Sign in
Project Home Downloads Wiki Issues Source
Asynchronous Image Loading with AndroidQuery
Updated Jul 13, 2012 by


All image loading features and code examples are available with our live demo app on Android Market.

We highly recommended that you try the demo app to get a feel of AQuery's image loading features.


Asynchronous image loading is easy with AQuery.


//load an image to an ImageView from network, cache image to file and memory"");

Cache Control

//load an image from network, but only cache with file

//this image is huge, avoid memory caching
boolean memCache = false;
boolean fileCache = true;"", memCache, fileCache);

Down Sampling (handling huge images)

//we are loading a huge image from the network, but we only need the image to be bigger than 200 pixels wide
//passing in the target width of 200 will down sample the image to conserve memory
//aquery will only down sample with power of 2 (2,4,8...) for good image quality and efficiency
//the resulting image width will be between 200 and 399 pixels

String imageUrl = "";, true, true, 200, 0);

Related Blog: Downsampling

Fallback Image

//if we are not able to load the image, use a default image (R.drawable.default_image)

String imageUrl = "";, true, true, 0, R.drawable.default_image);

//make image view "invisible" if image failed to load
imageUrl = "";, true, true, 0, AQuery.INVISIBLE);

//make image view "gone" if image failed to load, true, true, 0, AQuery.GONE);


//get the bitmap for a previously fetched thumbnail
String thumbnail = "";	
Bitmap preset = aq.getCachedImage(thumbnail);

//set the image view with a thumbnail, and fetch the high resolution image asynchronously
String imageUrl = "";, false, false, 0, 0, preset, AQuery.FADE_IN);


We can show the image loading progress by using the progress() method. Pass in the progress bar id, or any other view id to the progress method, and the view will be shown or hide to display loading progress.

String imageUrl = "";, false, false);

Sample grid item layout:

<RelativeLayout xmlns:android=""



//display the image with a predefined fade in animation
String imageUrl = "";, true, true, 0, null, 0, AQuery.FADE_IN);

Rounded Corner

The round option transform the image to a rounded corner image with a specified radius. Note that the value is in pixels (not dip).

Due to performance impact, round corner should not be used for large images.

String url = "";

ImageOptions options = new ImageOptions();
options.round = 15;, options);

Aspect Ratio

Preserve Image Aspect Ratio
String imageUrl = "";, true, true, 0, 0, null, AQuery.FADE_IN, AQuery.RATIO_PRESERVE);
Fixed Predefined Aspect Ratio
String imageUrl = "";, true, true, 0, 0, null, 0, AQuery.RATIO_PRESERVE);	

//1:1, a square, true, true, 0, 0, null, 0, 1.0f / 1.0f);, true, true, 0, 0, null, 0, 1.5f / 1.0f);	
//16:9, a video thumbnail, true, true, 0, 0, null, 0, 9.0f / 16.0f);, true, true, 0, 0, null, 0, 3.0f / 4.0f);


The aspect ratio feature will set the ImageView to use the ScaleType MATRIX and adjust its height to the correct aspect ratio.


If the image aspect ratio is taller then the desired aspect ratio, the anchor option can be used to control which vertical portion of the image should be displayed.

Anchor values:

  • 1.0 : Display top of the image
  • 0 : Display the center of the image
  • -1.0 : Display bottom of the image
  • AQuery.ANCHOR_DYNAMIC : Display image with a top bias for photos.

ImageOptions options = new ImageOptions();

options.ratio = 1;
options.anchor = 1.0;, options);

Custom Callback

String imageUrl = "";

final int tint = 0x77AA0000;, true, true, 0, 0, new BitmapAjaxCallback(){

	public void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status){
		//do something to the bitmap
		iv.setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);

File (Async)

Load image from a file asynchronously. Down sampling is recommended when loading huge images from camera or gallery to avoid out of memory errors.

File file = new File(path);        

//load image from file, down sample to target width of 300 pixels, 300);
File file = new File(path);

//load image from file with callback, false, 300, new BitmapAjaxCallback(){

    public void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status){
    	//do something with the bm

Duplicated URL

//AQuery detects duplicated image urls request and only fetches 1 image and apply them to all associated image views

String imageUrl = "";;

//no network fetch for 2nd request, image will be shown when first request is completed;


All the AQuery image methods uses the BitmapAjaxCallback internally. You can configure and use the callback directly if you prefer.

String imageUrl = "";	

//create a bitmap ajax callback object
BitmapAjaxCallback cb = new BitmapAjaxCallback();

//configure the callback

//invoke it with an image view;

Access Cached Images

//returns the cached file by url, returns null if url is not cached
File file = aq.getCachedFile(url);

Zoomable Web Image

In addition to ImageView, a WebView can be used to display an image along with Android build in zoom support for WebView. Image will be centered and fill the width or height of the webview depending on it's orientation.

private void image_zoom(){

	String url = "";;

List View Example

When working with AQuery, make sure the views you want to operate can be "findBy" the view or activity you created with the AQuery object. In the case for rendering list items, create an AQuery object with the item container view.


ArrayAdapter<JSONObject> aa = new ArrayAdapter<JSONObject>(this, R.layout.content_item_s, items){
	public View getView(int position, View convertView, ViewGroup parent) {
		if(convertView == null){
			convertView = getLayoutInflater().inflate(R.layout.content_item_s, null);
		JSONObject jo = getItem(position);
		AQuery aq = new AQuery(convertView);"titleNoFormatting", "No Title"));"publisher", ""));
		String tb = jo.optJSONObject("image").optString("tbUrl");, true, true, 0, 0, null, AQuery.FADE_IN_NETWORK, 1.0f);
		return convertView;

Delay Image Loading

AQuery provide a shouldDelay() method to help you decide whether to load expensive resources when the list is scrolling (flinging) really fast. It's recommended to delay load large images and other resources over the internet.

Please see javadoc for more detail.

ArrayAdapter<Photo> aa = new ArrayAdapter<Photo>(this, R.layout.photo_item, entries){
	public View getView(int position, View convertView, ViewGroup parent) {
		if(convertView == null){
			convertView = getLayoutInflater().inflate(R.layout.photo_item, parent, false);
		Photo photo = getItem(position);
		AQuery aq = new AQuery(convertView);;;
		String tbUrl = photo.tb;
		Bitmap placeholder = aq.getCachedImage(R.drawable.image_ph);
		if(aq.shouldDelay(position, convertView, parent, tbUrl)){, 0.75f);
		}else{, true, true, 0, 0, placeholder, 0, 0.75f);
		return convertView;

//apply any custom onScrollListener OnScrollListener(){...});

//apply the adapter;


The shouldDelay() method uses the setOnScrollListener() method and will override any previously non-aquery assigned scroll listener. If a scrolled listener is required, use the aquery method scrolled(OnScrollListener listener) to register your listener instead.

ListView, GridView, Gallery, and ExpandableListView are supported. For ExpandableListView, use the variation method:

shouldDelay(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent, java.lang.String url) 

ViewHolder Pattern

ViewHolder pattern optimize performance by caching the views returned by findViewById().

ArrayAdapter<JSONObject> aa = new ArrayAdapter<JSONObject>(this, R.layout.content_item_s, items){
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if(convertView == null){					
			convertView = getLayoutInflater().inflate(R.layout.content_item_s, null);
			holder = new ViewHolder();
			holder.imageview = (ImageView) convertView.findViewById(;
			holder.progress = (ProgressBar) convertView.findViewById(;
			holder = (ViewHolder) convertView.getTag();
		JSONObject jo = getItem(position);
		String tb = jo.optJSONObject("image").optString("tbUrl");
		AQuery aq = new AQuery(convertView);, true, true, 0, 0, null, 0, 1.0f);
		return convertView;

Cache Busting

Images on the web usually doesn't change. If your image changes with identical url and would like to refresh the image, simply set file and mem cache to false and it will force the image to be refetched.

String url = "";

//force a network refetch without any caching, false, false);

//force no proxy cache by appending a random number to url 
String url2 = url + "?t=" + System.currentTimeMillis();, false, false);

Network Failure Recovery

If network is disconnected and causing images to failed to load and use fallback images instead, the fallback images will be cached and continue to be served until the network connection is recovered.

When a next subsequent successful connection is established, the fallback image cache will be flushed and allow failed images to be reloaded.

Cache Configuration

By default, AQuery uses the internal file system to cache files, which is only accessible to your app. If you want to use the external SDCard for storing your cached files, use the setCacheDir() function.

File ext = Environment.getExternalStorageDirectory();
File cacheDir = new File(ext, "myapp");	

Sharing Image

In order to share resources to other apps, the file must be on the external storage (SDCard). The makeSharedFile() method create a copy of a cached url to a temporary folder in SDCard. You can then pass the file as an URI and share it with other apps, like Gmail or Facebook.

public void image_send(){
	String url = "";		
	File file = aq.makeSharedFile(url, "android.png");
	if(file != null){		
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
		startActivityForResult(Intent.createChooser(intent, "Share via:"), SEND_REQUEST);


More fine tuning can be done when an application starts. A good place to set the configuration is in the onCreate() method of the application.

public class MainApplication extends Application{

    public void onCreate() {     
        //set the max number of concurrent network connections, default is 4

	//set the max number of icons (image width <= 50) to be cached in memory, default is 20

	//set the max number of images (image width > 50) to be cached in memory, default is 20

	//set the max size of an image to be cached in memory, default is 1600 pixels (ie. 400x400)
	BitmapAjaxCallback.setPixelLimit(400 * 400);
	//set the max size of the memory cache, default is 1M pixels (4MB)


AQuery provides few utility functions to help you control ajax and caching behavior.

Clean Up

If you use file cache for images, regularly clean the cache dir when the application exits.


protected void onDestroy(){
	//clean the file cache when root activity exit
	//the resulting total cache size will be less than 3M	


protected void onDestroy(){

    		//clean the file cache with advance option
    		long triggerSize = 3000000; //starts cleaning when cache size is larger than 3M
    		long targetSize = 2000000;	//remove the least recently used files until cache size is less than 2M
    		AQUtility.cleanCacheAsync(this, triggerSize, targetSize);

Low Memory

Low memory happens when the device is overloaded with apps. When this happens, we want to remove all images from memory cache.

public class MainApplication extends Application{

    public void onLowMemory(){	

	//clear all memory cached images when system is in low memory
	//note that you can configure the max image cache count, see CONFIGURATION
Comment by, Jan 21, 2013

Firstly, I would like to say! wow you guys have done an awesome job with this!

I am trying to implement the first ListView? example, I am stuck... On this line: ArrayAdapter?<JSONObject> aa = new ArrayAdapter?<JSONObject>(this, R.layout.list_item, items){

Where do I get the "items"? it keeps giving me an error when building an items array, I'm not sure what to do here.


Comment by, Apr 10, 2013

Can we override AQuery methods in android. Please provide me an example. Thanks in Advance....! Like"titleNoFormatting", "No Title"));
is it possible to override text method here..

Comment by, Jun 11, 2013

Is there any sample code that uploads image to server using the most great library AQuery?

Comment by, Jun 25, 2013

The code was wrong, I can do this!! . <a href="">click here</a>

Comment by, Jul 23, 2013


When using setListAdapter(aa); I can get the onListItemClick called

while; don't. Please help, the setListAdaper is too slow in compare to



Comment by, Oct 29, 2013

Hi,I like your project

Comment by, Dec 9, 2013
if(aq.shouldDelay(position, convertView, parent, holder.prodImagePath)){;
} else {, false, true, 0, 0, null, AQuery.FADE_IN);

Throwing NPE... Please give me Solution.

Comment by, Jan 24, 2014

android-query-full.0.26.7.jar를 사용하여 이미지를 보여주는데 버그를 발견했습니다. 이미지를 round처리하기 위해 ImageOptions?를 이용했고 이미지가 존재하지 않을때를 처리하기 위해 fallback을 사용했습니다. 버그는 이미지가 유효하지 않을때 bitmap이 생성되지 않았는데 round처리 하는 과정에서 NullPointException?이 발생합니다. 위치는 BitmapAjaxCallback?.java의415라인 입니다.

이 부분이구요.. if(round > 0){

bm = getRoundedCornerBitmap(bm, round);

아래와 같이 null처리가 추가되어야 합니다. if(round > 0){

if(bm != null){
bm = getRoundedCornerBitmap(bm, round);

Thanks you!!

Comment by, Apr 6, 2014

Thanks for the Library. Really helpful

Comment by, Apr 24, 2014

Hello here I am newbie in developing my idea of a developer who seeks apli eberger an image on a local server view it in full screen every 5 seconds recommancer Image not available it not existing recommancer all 5s are pouriez you help me?

Comment by, Jul 15, 2014

By using Aquery sometime duplicate image in listview row if the row doesn't contain any image...

Sign in to add a comment
Powered by Google Project Hosting