I am currently adding ImageViews and setting the images within a ViewHolder. The creation time is not smooth and the first scroll through is not smooth either. Any suggestion or an alternative to having smooth dynamic views within a viewholder?
ViewHolder
class ViewHolderRecipientExpanded extends RecyclerView.ViewHolder {
private LinearLayout mFlagLayout;
//
public ViewHolderRecipientExpanded(View v) {
super(v);
mFlagLayout = (LinearLayout) v.findViewById(R.id.flagLayout);
//
}
public void initiateRecipientsDetails() {
Recipient recipient = objectList.get(getAdapterPosition());
int totalAmountOfCountries = recipient.getFlags() != null ? recipient.getFlags().size() : 0;
//
int countriesLimitedToThree = recipient.getFlags() != null ? (totalAmountOfCountries > 3 ? 3 : totalAmountOfCountries) : 0;
View imageView;
ImageView image;
Drawable drawable;
for (int i = 0; i < countriesLimitedToThree; i++) {
imageView = inflater.inflate(R.layout.view_image_flag, null);
image = (ImageView) imageView.findViewById(R.id.image);
drawable = new BitmapDrawable(context.getResources(), recipient.getFlags().get(i).getFlag());
image.setImageDrawable(drawable);
mFlagLayout.addView(imageView);
}
}
}
Load your images asynchronously, and cache them in memory when they are not in view. This will not block the UI thread when loading images, allowing the user to scroll even if the images aren't loaded yet. Though, it will still take some time for the images to actually appear.
There are also a number of great libraries that will handle this for you:
Picasso
Glide
Fresco
Related
I have noticed that a ListView in my application has started to stutter quite badly all of a sudden.
I am using Volley to load images for my listview items - downloading and caching the images are fine and scroll smooth as butter.
However I currently have a spinner that sits on top of the NetworkImageView while I wait for the image to load. The lag comes in once the image has successfully loaded - I set the spinner to be invisible and the image to visible. Changing the visibility of these items seems to be the source of the lag.
I am currently using the View Holder pattern, my onResponseLoad looks like the following:
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null){ //Check that the image is not null
ProgressBar progress = holder.getProgress(); //Find Spinner - this doesnt cause lag
progress.setVisibility(View.GONE); //Hide spinner (This causes lag)
img.setVisibility(View.VISIBLE); //Image is a network image from the holder (This causes lag)
}
}
(Note that commenting out those two offending lines results in buttery smooth scrolling again)
The other strange thing is that I haven't touched this part of the application in some time and in my current live version, as well as previous commits there is no lag. Comparing my current code base to previous non-lagging versions show that there has been 0 change to the code surrounding this aspect of the application. Furthermore other lists that I have implemented using almost the exact same technique have not experienced this issue.
The only thing I can think of that could be different is that I am now using the latest version of Gradle - although I don't think that should have an impact at run-time.
I am at a total loss as to what is going on, would appreciate any insight on what I should be doing to achieve smooth ListView scrolling (or what may have lead to my implementation's degradation)
EDIT: Posting code of getView() as requested
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View placeSelectorView = convertView;
PlaceViewHolder placeSelectorHolder = null;
if(placeSelectorView == null){ //If we are creating the row for the first time
LayoutInflater inflater = (LayoutInflater) mCtx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //Inflate the view
placeSelectorView = inflater.inflate(R.layout.place_selector, parent, false); //Get the view
placeSelectorHolder = new PlaceViewHolder(placeSelectorView); //Create holder object
placeSelectorView.setTag(placeSelectorHolder); //Attach reference to the view
}else{
placeSelectorHolder = (PlaceViewHolder) placeSelectorView.getTag(); //Load holder from memory
if(!placeSelectorHolder.isHasImage()){ //Need to optimise this
placeSelectorHolder.getLayout().addView(placeSelectorHolder.getrLayoutThumbnail(), 0);
placeSelectorHolder.setHasImage(true);
}
if(!placeSelectorHolder.isSpinnerVisible()){
placeSelectorHolder.getProgressBar().setVisibility(View.VISIBLE);
placeSelectorHolder.getPlaceImg().setVisibility(View.GONE);
placeSelectorHolder.setSpinnerVisible(true);
}
}
POI place = (values.get(position)); //Get POI object for the place
POI parentPlace = getParent(place); //Get parent POI for place
placeSelectorHolder.getPlaceName().setText(place.getName());
if(parentPlace != null){ //If place has a parent POI
placeSelectorHolder.getParentPlaceName().setText(parentPlace.getName());
}else{ //We don't want the parent text in the view
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) placeSelectorHolder.getParentPlaceName().getLayoutParams();
layoutParams.weight = 0; //Setting weight to 0 will remove it from the LinearLayout
placeSelectorHolder.getParentPlaceName().setLayoutParams(layoutParams);
}
final PlaceViewHolder holder = placeSelectorHolder;
loadThumbnail(holder, place);
return placeSelectorView;
}
public void loadThumbnail(final PlaceViewHolder placeSelectorHolder, POI place){
RealmList<poiPhoto> photos = place.getPhotos();
String mUrl;
if(!photos.isEmpty()){
mUrl = photos.get(0).getSmall();
}else{
mUrl = "";
}
final NetworkImageView placeImg = placeSelectorHolder.getPlaceImg();
if(!mUrl.equals("")){ //If there is an Image Available
ImageLoader imageLoader = ServerSingleton.getInstance(getContext()).getImageLoader(); //Get volley imageloader from Singleton
imageLoader.get(mUrl, new ImageLoader.ImageListener() { //Custom get so we can use override onResponse and OnErrorResponse
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null){ //Check that the image is not null
ProgressBar progressBar = placeSelectorHolder.getProgressBar(); //Find Spinner
placeImg.setVisibility(View.VISIBLE);
if(progressBar != null) progressBar.setVisibility(View.GONE); //Make the spinner invisible
placeSelectorHolder.setSpinnerVisible(false);
}
}
#Override
public void onErrorResponse(VolleyError error) {
//TO-DO: Get an error image
}
});
placeImg.setImageUrl(mUrl, imageLoader); //Send the request
placeSelectorHolder.setHasImage(true);
}else{ //There is no image
LinearLayout layout = placeSelectorHolder.getLayout(); //Find the horizontal layout
layout.removeView(placeSelectorHolder.getrLayoutThumbnail()); //Remove the Thumbnail layout
placeSelectorHolder.setHasImage(false);
}
}
I'm extremely new to Android programming. Right now I'm building a very simple app so i can get the hang of things.
Basically i have:
- Background
- ImageView
- ImageButton.
Every time I click the ImageButton, it cycles through a list of images I have stored in an array. However I'm ending up skipping a lot of frames.
private static ImageButton button;
private static ImageView current;
private int index;
int[] images = {R.drawable.image1, R.drawable.image2};
public void buttonClick() {
current = (ImageView)findViewById(R.id.imageView);
button = (ImageButton)findViewById(R.id.imageButton);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
current.setImageResource(images[index]);
if(index == (images.length - 1)) {
index = 0;
}
else {
index++;
}
}
}
);
}
Any idea what is causing it to skip frames, and what I can do to fix it? Is it because my image files are too big? They are about 788kb each and 1920x1120.
Thank you.
You must be doing it off the ui thread.
Images/Bitmaps should be efficiently loaded.
Refer example on official page: https://developer.android.com/training/displaying-bitmaps/index.html
Yes. The size is the image is probably causing the skipping of frames. Try using smaller images to verify that your images are the problem.
As described in many tutorials and in Android developers pages too, I'm using an async task to load images as thumbnails in a ListView. The task loads full size image from SDcard, resize it and put it in the ImageView of list item's layout.
Everything works well, except for the fact that after scrolling list fast up & down, the image of a single visible element is updated two or three times with different images before getting the right one.
This behavior is related, in my opinion, to the recycling views in ListView: when an asynctask is ready to inject the list's element-X image in the referred view, the view itself might be already been recycled and assigned to list's element-Y.
I'm conscious about some ugliness of my code, for example the fact that I've implemented neither volatile nor persistent cache for thumbnails (targeted for next release), but the problem would be only partially hidden by that.
I found a possible solution using libraries for loading image, but I'm investigating how to fix in my code because the problem is more generally related to using async code in conjunction with list and today I deal with images, but tomorrow I'could face the same problem loading text or any other kind of data.
Possible solutions I'm investigating are:
Inform the asynctask about the item of the list it is working for, once loaded image updates it only if the item is visible
When list detaches the view from element (how can I detect this?), stop the asynctask
Override list's OnScrollListener to check when OnScroll event happens if an item exits from visible items' list and the stop its asynctask, if exists.
Is one of these solutions viable or con you suggest a different one?
This is my list's adapter (I'm using an expandable list in a fragment):
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
Log.i(TAG, "ExpandableListAdapter.getChildView entered, getting view n. " + groupPosition + "-" + childPosition + ", convertview = " + convertView);
ViewHolder holder;
if (convertView == null) {
convertView = inf.inflate(R.layout.selfie_list_item_layout, parent, false);
holder = new ViewHolder();
holder.date = (TextView) convertView.findViewById(R.id.selfieListItemDateView);
holder.place = (TextView) convertView.findViewById(R.id.selfieListItemPlaceView);
holder.thumb = (ImageView) convertView.findViewById(R.id.selfieListItemThumbView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Integer mChildIndex = (Integer) getChild(groupPosition, childPosition);
SelfieItem mChildObj = selfies.get(mChildIndex);
String mText = mChildObj.getDate().toString();
holder.date.setText(mText);
holder.thumb.setImageBitmap(BitmapFactory.decodeResource(convertView.getResources(), R.drawable.selfie_place_holder));
File selfieFile = mChildObj.getFile();
new LoadSelfieTask(mFragmentContext).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, selfieFile, holder.thumb);
return convertView;
}
And the following is async code:
#Override
protected Bitmap doInBackground(Object... params) {
File selfieFile = (File)params[0];
Bitmap mySrcBitmap = null;
Bitmap myDestBitmap = null;
if (selfieFile.exists()) {
mySrcBitmap = BitmapFactory.decodeFile(selfieFile.getAbsolutePath());
}
if (mySrcBitmap != null) {
// Get info about view to be updated
mImageViewToBeUpdated = (ImageView) params[1];
mImageHeight = mImageViewToBeUpdated.getHeight();
mImageWidth = mImageViewToBeUpdated.getWidth();
if (mySrcBitmap.getWidth() >= mySrcBitmap.getHeight()){
myDestBitmap = Bitmap.createBitmap(
mySrcBitmap,
mySrcBitmap.getWidth()/2 - mySrcBitmap.getHeight()/2,
0,
mySrcBitmap.getHeight(),
mySrcBitmap.getHeight()
);
}else{
myDestBitmap = Bitmap.createBitmap(
mySrcBitmap,
0,
mySrcBitmap.getHeight()/2 - mySrcBitmap.getWidth()/2,
mySrcBitmap.getWidth(),
mySrcBitmap.getWidth()
);
}
mySrcBitmap = Bitmap.createScaledBitmap(myDestBitmap, mImageWidth, mImageHeight, true);
}
return mySrcBitmap;
}
Thanks in advance for your answers.
If you need something quick, try Picasso http://square.github.io/picasso/
Your code is, for each row, create an AsyncTask to fetch image from external storage. You will create another AsynTask to fetch the same image again when you scroll back to a row item. I would suggest you to create a cache to store the result of AsynTask, and have proper cache replacement policy.
I found the answer to my question in the example code of this Android Developers Training Lesson.
In ImageWorker.java we can find the method that launches the backgroud task thad loads the image:
/**
* Load an image specified by the data parameter into an ImageView (override
* {#link ImageWorker#processBitmap(Object)} to define the processing logic). A memory and
* disk cache will be used if an {#link ImageCache} has been added using
* {#link ImageWorker#addImageCache(android.support.v4.app.FragmentManager, ImageCache.ImageCacheParams)}. If the
* image is found in the memory cache, it is set immediately, otherwise an {#link AsyncTask}
* will be created to asynchronously load the bitmap.
*
* #param data The URL of the image to download.
* #param imageView The ImageView to bind the downloaded image to.
*/
public void loadImage(Object data, ImageView imageView) {
if (data == null) {
return;
}
BitmapDrawable value = null;
if (mImageCache != null) {
value = mImageCache.getBitmapFromMemCache(String.valueOf(data));
}
if (value != null) {
// Bitmap found in memory cache
imageView.setImageDrawable(value);
} else if (cancelPotentialWork(data, imageView)) {
//BEGIN_INCLUDE(execute_background_task)
final BitmapWorkerTask task = new BitmapWorkerTask(data, imageView);
final AsyncDrawable asyncDrawable =
new AsyncDrawable(mResources, mLoadingBitmap, task);
imageView.setImageDrawable(asyncDrawable);
// NOTE: This uses a custom version of AsyncTask that has been pulled from the
// framework and slightly modified. Refer to the docs at the top of the class
// for more info on what was changed.
task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR);
//END_INCLUDE(execute_background_task)
}
}
A reference to AsyncTask instance is saved in an AsyncDrawable class:
/**
* A custom Drawable that will be attached to the imageView while the work is in progress.
* Contains a reference to the actual worker task, so that it can be stopped if a new binding is
* required, and makes sure that only the last started worker process can bind its result,
* independently of the finish order.
*/
private static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference =
new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
At the end of background activity, the AsyncTask verifies if it is the last to be "attached" to the view it has to update and performs update only if no other task have been "attached" to the view
/**
* Returns the ImageView associated with this task as long as the ImageView's task still
* points to this task as well. Returns null otherwise.
*/
private ImageView getAttachedImageView() {
final ImageView imageView = imageViewReference.get();
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (this == bitmapWorkerTask) {
return imageView;
}
return null;
}
/**
* Once the image is processed, associates it to the imageView
*/
#Override
protected void onPostExecute(BitmapDrawable value) {
//BEGIN_INCLUDE(complete_background_work)
// if cancel was called on this task or the "exit early" flag is set then we're done
if (isCancelled() || mExitTasksEarly) {
value = null;
}
final ImageView imageView = getAttachedImageView();
if (value != null && imageView != null) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onPostExecute - setting bitmap");
}
setImageDrawable(imageView, value);
}
//END_INCLUDE(complete_background_work)
}
Cancelling AsyncTasks? Is that a good idea? I have found that it does not work many times and postExecute() is always called so its a possibility your image will be still laid out in the listview, maybe a wrong one which will further mess up your scenario..
I have a HorizontalScrollView which contains a LinearLayout to hold all my view. I add about 20 RelativeLayout which contains a ImageView and TextView to the LinearLayout. I would like to only load images if the ImageView is on the screen (as I scroll to the ImageView).
I tried following this post to use getHitRect(), on the thumbnail, however, the Rect (bounds) for the thumbnail is always 0, 0-0, 0, resulting in my method to return false. What am I doing wrong?
thumbnailLayout is my LinearLayout inside the HorizontalScrollView
thumbnailScroll is my HorizontalScrollView
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e(TAG, "running");
for (int i = 0; i < thumbnailLayout.getChildCount(); i++) {
RelativeLayout view = (RelativeLayout) thumbnailLayout.getChildAt(i);
ImageView thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
if (thumbnailIsOnScreen(thumbnail)) {
Log.e(TAG, items.get(i).getTitle() + " has downloaded");
app.setImage(items.get(i).getThumbnailSmall(), thumbnail);
}
}
}
});
private boolean thumbnailIsOnScreen(ImageView thumbnail) {
Rect bounds = new Rect();
thumbnail.getHitRect(bounds);
Rect scrollBounds = new Rect(thumbnailScroll.getScrollX(), thumbnailScroll.getScrollY(),
thumbnailScroll.getScrollX() + thumbnailScroll.getWidth(), thumbnailScroll.getScrollY()
+ thumbnailScroll.getHeight());
return Rect.intersects(scrollBounds, bounds);
}
Edit
I'm tred using TreeObserver and found that my method to check if the thumbails are on screen is wrong. It still grabs all the images, and constantly loops (because I'm using onPreDrawListener?)
thumbnailLayout.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
Log.e(TAG, "running");
for (int i = 0; i < thumbnailLayout.getChildCount(); i++) {
RelativeLayout view = (RelativeLayout) thumbnailLayout.getChildAt(i);
ImageView thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
if (thumbnailIsOnScreen(thumbnail)) {
Log.e(TAG, items.get(i).getTitle() + " has downloaded");
app.setImage(items.get(i).getThumbnailSmall(), thumbnail);
}
}
return true;
}
});
Have you thought about using ViewPager?
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
If that doesn't fit your design you need to override the ScrollView -> function onScrollChanged and there check if your image in screen check the image (left?) position compared to the scroll position.
You need a ListView but there isn't native HorizontallListView in android. You can try HorizontallListView by DevSmart. It's works like a native list view, with adapters and custom views if you want.
I'm showing list with one ImageView on every row of list.
For that, I download images from net in another AsyncTask using Drawable.createFromStream
And store them as Drawable in ArrayList which I pass to my Adapter class extending BaseAdapter class.
But the images are taken with high-resolution camera, so may be of very large size.
And I'm getting OutOfMemory error.
So my questions :
What is more efficient, storing images as drawable or as bitmap or any other format?
Am I doing right, by storing all images in memory(in array list). i.e. I'm thinking, once I get a image, I will show it on ImageView and will not store in ArrayList.
is there any way, I can compress the images after download, so they will take less space in memory.
My total code is present here
Android documentation provides a very good example showing how to handle bitmaps in your android app. The example uses an on-disk and in-memory cache and loads the images in the background. By doing so, the main UI thread is not slowed down by loading the images.
Loading Bitmaps effectively
In the example the images are loaded from picasa. It's easy, however, to adapt the example, so that pictures stored locally are used. You simply have to write your own ImageLoader extending from the 'ImageResizer':
public class ImageLoader extends ImageResizer {
public ImageLoader(Context context, int imageWidth, int imageHeight) {
super(context, imageWidth, imageHeight);
}
public ImageLoader(Context context, int imageSize) {
super(context, imageSize);
}
#Override
protected Bitmap processBitmap(Object data) {
return decodeSampledBitmapFromFile((String)data, imageWidth, imageHeight);
}
}
But to answer your question directly: it's ok to load images as Bitmaps. But you have to use a cache and weak references, so that the images can be garbage collected in case they are not visible on the screen. Caching them and using a background task for loading allows for a slick UI.
I don't see any efficiency in storing high-density images into memory - it's totally not recommended to store large ammount of images as bitmaps in memory (good for you that you have a good device ;))
See p.1
Try downscaling the images to fit the device's needs - that's not a simple job though. Also, see View.setTag(Object tag)
The adapter
public class MyImageListAdapter extends BaseAdapter implements ImageLoadingNotifier {
private LayoutInflater inflater = null;
public MyImageListAdapter() {
inflater = LayoutInflater)HomeActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return listImageInfo.size();
}
public Object getItem(int position) {
return listImageInfo.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.list_row, null);
}
TextView tvName = (TextView) vi.findViewById(R.id.tv_name);
TextView tvTime = (TextView) vi.findViewById(R.id.tv_time);
ImageView image = (ImageView) vi.findViewById(R.id.iv_image);
final Button btnDelete = (Button) vi.findViewById(R.id.btn_delete);
image.setImageDrawable(R.drawable.default_placeholder);//set default place-holder
new GetDrawableFromUrl(listImageInfo.get(position), vi).execute();
tvName.setText("Name: " + listImageInfo.get(position).getImage_name());
tvTime.setText("Date: " + listImageInfo.get(position).getDate_created());
btnDelete.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final int position = listView.getPositionForView((View) v.getParent());
positionOgBtnToDelete = position;
Log.v("delete btn clicked", "delete btn no: " + position);
Toast.makeText(HomeActivity.this, "Btn delete position: " + position, Toast.LENGTH_LONG).show();
showAlertToConfirmDelete();
}
});
return vi;
}
}
The AsyncTask GetDrawableFromUrl
public class GetDrawableFromUrl extends AsyncTask<Void, Void, Drawable> {
public ImageInfo imageInfoObj;
private ImageView view;
GetDrawableFromUrl(ImageInfo imageInfo, ImageView view) {
imageInfoObj = imageInfo;
this.view = view;
}
#Override
protected Drawable doInBackground(Void... params) {
try {
return Drawable.createFromStream(((java.io.InputStream) new java.net.URL(imageInfoObj.getImageUrl()).getContent()), "src_name");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Drawable drawable) {
if (drawable != null) {
//imageInfoObj.setImage(drawable);
this.view.setImageDrawable(drawable);
//listImageInfo.add(imageInfoObj); //this one is called when the json is parsed
showImagesInList(); //don't know what it does (??)
}
}
}
The JSON parsing
JSONArray jsonArray = jsonObj.getJSONArray("result");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObjInner = jsonArray.getJSONObject(i);
ImageInfo imageInfo = new ImageInfo();
imageInfo.setImageUrl("http://www.dvimaytech.com/markphoto/" + jsonObjInner.getString("image"));
//new GetDrawableFromUrl(imageInfo).execute(); //don't needed here
imageInfo.setEmail(jsonObjInner.getString("emailid"));
imageInfo.setImage_id(jsonObjInner.getString("image_id"));
imageInfo.setImage_name(jsonObjInner.getString("image_name"));
imageInfo.setAmount(jsonObjInner.getString("amount"));
imageInfo.setImage_description(jsonObjInner.getString("image_description"));
imageInfo.setDate_created(jsonObjInner.getString("date_created"));
listImageInfo.add(imageInfo);
}
And, the use of any kind of List of images becomes unnecesary :)
Instead of starting the async task (GetDrawableFromUrl) when parsing the json objects, you can start the task in getView(...) method. This way you will not be constrained to store the drawables into that ArrayList, since you'll be modifying the ImageView after the image was downloaded. And, by default, you can put a placeholder, until the image is downloaded (or in case there are some network errors).
This way the images will start downloading only when the getView method will be called for that specific item.
The bottom line is that each view from the ListView will keep a reference to it's specific drawable (that was set using vi.setTag(image).
If this helps somehow, you know what to do ;)
There is pretty good library calling AQuery. YOu can use it and simple get all stuff like memory and file caching by writting only 2 line of code. So you even wouldn't need to prepare a drawable, you can call it directly from Adapter.getView() callback.
AQuery aq = new AQuery(rowView);
aq.id(R.id.image).image(url, false, true);
Hope it help you!
From AQuery docs:
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 = "http://farm6.static.flickr.com/5035/5802797131_a729dac808_b.jpg";
aq.id(R.id.image1).image(imageUrl, true, true, 200, 0);