Android loading image from url performance - android

I have classic AsyncTask to load image:
private class DownloadImageTask extends AsyncTask<String,Void,Bitmap> {
Bitmap bitmap = null;
#Override
protected Bitmap doInBackground(String... str) {
try{
InputStream in = new java.net.URL(picture).openStream();
bitmap = BitmapFactory.decodeStream(new SanInputStream(in));
//viewPicture.setImageBitmap(bitmap);
viewPicture.setBackgroundDrawable(new BitmapDrawable(bitmap));
}
catch(Exception e){
e.printStackTrace();
}
return bitmap;
}
}
But loading of image is to long. When I start this activity, everything is loaded besides image and only after waiting a second I can see it. What is the problem?

viewPicture.setBackgroundDrawable(new BitmapDrawable(bitmap));
should be done on the UI thread, in the onPostExecute method of your AsyncTask.
Also, close the stream (if !null) you use with a nice finally block of your try/catch.
And don't worry about the time, it's the way to go.

Simple... because it takes time to open connection to the resource URL and download all the required bytes. Moreover, the performance may also vary on the speed of your Internet connection.

Related

How to load quickly the image from the url in the ImageView of the normal android view(not list view)?

My internet connection is very fast. Despite that my image loads very slow in the app. Here is the code i have been using. As suggested I have been using async method to perform certain task seperately..
public class ItemPage extends Activity{
ImageView image;
String url;
#Override
protected void onCreate(Bundle savedInstanceState) {
image = (ImageView) findViewById(R.id.img);
//getting url from the parent activity
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if(extras != null) url = extras.getString("bigurl");
//async call
new DownloadFilesTask().execute();
}
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> { //working part
Drawable drawable;
#Override
protected Void doInBackground(Void... params) {
try {
drawable =drawableFromUrl(url);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result) {
image.setImageDrawable(drawable);
}
}
public static Drawable drawableFromUrl(String url) throws IOException {
Bitmap x;
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.connect();
InputStream input = connection.getInputStream();
x = BitmapFactory.decodeStream(input);
return new BitmapDrawable(x);
}
}
Please help me. Is there any way to load the image faster from the url? Thanks in advance for your time.
i think you want to use Aquery Library .
it is load images very speedly.
refer this link
This works for me.
Bitmap mIcon_val;
URL newurl;
private void loadImage() {
Thread backgroundThread = new Thread() {
#Override
public void run() {
// do second step
try {
newurl = new URL(image_url);
mIcon_val = BitmapFactory.decodeStream(newurl
.openConnection().getInputStream());
} catch (MalformedURLException e) {
} catch (IOException e) {
}
Message msg = Message.obtain();
msg.what = 123;
handler.sendMessage(msg);
}
};
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 123:
imageView.setImageBitmap(mIcon_val);
break;
}
}
};
For calling the thread, you can use
backgroundThread.start();
My internet connection is very fast. Despite that my image loads very slow in the app.
It doesnt mean you can download image very fast when you have a really fast connection, it could be that the web server have a limit download speed for each connection, or the server is far from your current location. I would recommend to check the download speed of the server you are trying to connection first, if it is slow then it is not code but the server itself.
you may try using picasso library.it has several functions to compress,crop images that may help in downloading images at better rates.the link provides the full documentation of usage of the library-
http://square.github.io/picasso/
Here's something you can do to speed up the image processing side of things.
When you decode the stream you are converting it to an in-memory raster format. A 32bit image at 500x500 will take 1 mb of memory (500x500x4bytes). the native pixel format varies by device, and the fastest performance is to match the bitmap's pixel format to the system's pixel format so the system doesn't need to convert the image from it's native format to the window format.
Older devices in particular will use the 16 bit format. The image would be stored at 32bits, and then converted to 16bits when it's drawn to the screen. On these devices, you would be saving half the memory storage and avoiding a costly pixelwise conversion by decoding the image at 16 bits instead of at 32 bits. On newer devices that have the memory, it's better to store the image at 32 bits to avoid the conversion penalty.
So somewhere early on, store the pixel format that is used by the system. It will either be a 16 bit format (RGB_565) or a 32 bit format (8bits per pixel per color)
// default to 32 bits per pixel
Config bitmapConfig = Bitmap.Config.ARGB_8888 ; //RGB_565 | ARGB_8888
WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
int bmp_cfg = wm.getDefaultDisplay().getPixelFormat();
if (bmp_cfg == PixelFormat.RGBA_8888 || bmp_cfg == PixelFormat.RGBX_8888 || bmp_cfg == PixelFormat.RGB_888){
bitmapConfig = Bitmap.Config.ARGB_8888;
} else {
bitmapConfig = Bitmap.Config.RGB_565;
}
Later, when you are decoding the bitmap, use the window manager's default pixel format so that it will create the bitmap with the correct pixel format while decoding (rather than converting in a second pass)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = bitmapConfig; // match pixel format to widnow system's format
Bitmap bitmap = BitmapFactory.decodeStream(input, null, options);
bitmap = Bitmap.createBitmap(bitmap);
You can also play with the sample size to adjust the bitmap, but at 500x500 you probably need the whole image anyway.

optimize android code snippet - better design approach?

I've this snippet of code which I would like to optimize it. I've a method which is been called regularly by the OSMdroid library to load tons of maptiles. This method directly invokes the filestream and load the bitmap directly and will return the bitmap once loaded on the main UI thread.
Although I've managed to run in the background using AsyncTask with parallel executor. Sometimes with plenty number of overlays (itemized) in the mapview this snippet of code runs slower as GC_FO_ALLOC is triggered regularly for allocation, and in my log messages I get Grow Heap (frag case). I tried many ways to work around, but not effective enough. For some reason this task is being executed on main thread is my feeling as in my log messages I also get Skipped xx frames, the application may be doing lot of task. Any idea how can this be made better? The thing is method has to return back, as soon as it loads, there by how can I allow this method to wait until mapview is not panned or zoomed, then load the tiles?
#SuppressWarnings("deprecation")
#Override
public Drawable getDrawable(final InputStream aFileInputStream) throws LowMemoryException {
try {
df = new DisplayFile();
df.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, aFileInputStream);
return new BitmapDrawable(df.get());
} catch (final OutOfMemoryError e) {
System.gc();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
private class DisplayFile extends AsyncTask<InputStream, Bitmap, Bitmap> {
InputStream path;
#Override
protected Bitmap doInBackground(InputStream... arg0) {
path = arg0[0];
BitmapFactory.Options mBitOpt = new BitmapFactory.Options();
mBitOpt.inDither = false;
mBitOpt.inSampleSize = 1;
mBitOpt.inPurgeable = true;
mBitOpt.inInputShareable = true;
mBitOpt.inPreferredConfig = Bitmap.Config.ARGB_8888;
final Bitmap mBitmap = BitmapFactory.decodeStream(path,null,mBitOpt);
return mBitmap;
}
}
As far as I understand, you are trying to display an offline map using osmdroid.
Android is unable to load "tons of map tiles" in memory, because it just doesn't provide enough memory heap to each application.
This is why osmdroid has advanced mechanisms (background loading, LRU cache, ...)
Why are you not just using these standard osmdroid mechanisms?
Look at this post for more details about off-line maps on osmdroid: Download maps for osmdroid

Show image from URL, Android-app goes extremly slow

I am trying to show an image in my app from an URL, but when (only when) the bitmap is showed the app gets way too slow. The app goes OK, but when I load the image it goes extremly slow. Someone can help with this?
So I have a class named ImageDownload which does the download and in my Fragment I have:
new ImageDownload((ImageView) login_image, this.getActivity().getApplicationContext(),"login_image")
.execute(path);
Here is my download Class:
public class ImageDownload extends AsyncTask<String, Void, Bitmap> {
private Context mContext;
private String filename;
ImageView bmImage;
public ImageDownload(ImageView bmImage, Context mContext, String filename) {
this.bmImage = bmImage;
this.mContext = mContext;
this.filename = filename;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in,null,null);
//EDIT:
in.close();
// The isuue is not soved yet
} catch (Exception e) {
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Then the problem with the size of your ImageBitmap & the RAM size of the tablet. It is taking too much of RAM on loading the ImageBitmap on RAM. You can detect this by looking into the log, how frequent System.gc() is getting called, as the system facing too frequent page misss than page hit, its almost like thrashing problem. I'm sure the system is calling .gc() so frequently and as the System.gc() is called in GUI thread, it is disturbing UI experience.
You should be using Google's Volley library
Use Picasso. It's simple and cool.
I finally found the response. Check it out. it might help you in the future. Thank you to all of you. This works perfectly:
http://www.technotalkative.com/android-load-images-from-web-and-caching/

how to make Android ImageView downloading image gradually

I am building an application that downloads and displays several images. Everything is going well.
But i want it display an image as soon as it downloading. Not when its done downloading. I'm pretty sure it's called something like Interlaced, since i use PNGs.
This is part of code i've done to download and display an image :
private class DownloadTask extends AsyncTask<String, Integer, Bitmap> {
#Override
protected void onPostExecute(Bitmap result) {
ivGambar.setImageBitmap(result);// ivGambar is an ImageView
pbDetail.setVisibility(View.INVISIBLE);
}
#Override
protected Bitmap doInBackground(String... pa) {
try {
return BitmapFactory.decodeStream((InputStream) new URL(pa[0])
.getContent());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Is it can be done in Android? How?
Thank you.
I don't know exactly, but you can try to read progressively from the URL and then decode the stream even if it is incomplete, then doing it as you read from the stream, storing it in a buffer.
You can use URL.openStream() to get the stream, copy progressively the contents in a byte array (growing it if needed) and then use BitmapFactory.decodeByteArray to get the decoded partial bitmap (if the data is enough of course).
You could even use ByteArrayOutputStream as a buffer.
Be careful not to do this too often as it may slow down everything massively.

android java.lang.OutOfMemoryError: bitmap size exceeds VM budget

i've some leaks problems.
What i'm doing is loading some pictures in a table. I've created an asyncronous class for loading images.
In my table while i'm cycling the array I add my class
final LoaderImageView image = new LoaderImageView(getContext(),vgood[i].getImageUrl(),(int)(ratio *80),(int)(ratio *80));
row.addView(image);
In my asyncronous class i'm loading images from this
return Drawable.createFromStream(((java.io.InputStream)new java.net.URL(url).getContent()), "name");
Called by
public void setImageDrawable(final String imageUrl) {
mDrawable = null;
mSpinner.setVisibility(View.VISIBLE);
mImage.setVisibility(View.GONE);
new Thread(){
public void run() {
try {
mDrawable = getDrawableFromUrl(imageUrl);
imageLoadedHandler.sendEmptyMessage(COMPLETE);
} catch (MalformedURLException e) {
imageLoadedHandler.sendEmptyMessage(FAILED);
e.printStackTrace();
} catch (IOException e) {
imageLoadedHandler.sendEmptyMessage(FAILED);
e.printStackTrace();
}
};
}.start();
}
When i've a lot of images to load the app crashes due to out of memory caused by this line
return Drawable.createFromStream(((java.io.InputStream)new java.net.URL(url).getContent()), "name");
How can i fix that? where i'm going wrong?
thank you
Never load any tiles that you don't need. "am collecting all bitmaps from sdcard" suggests that you are decompressing every image you might ever need, which would be the wrong approach.
Use smaller tiles. 256x256 is a good size.
Load them as Config.RGB565 (i.e. 16bpp).
Regularly recycle() Bitmaps you don't need.
Basically you need to implement some sort of most-recently-used (MRU) Bitmap cache
Extrated From
Android: "java-lang-outofmemoryerror-bitmap-size-exceeds-vm-budget-android" While loading bitmaps from sdcard?

Categories

Resources