I am having a customized list view in my application, which is showing an image and text.
The Image I am getting from URL, using the code below:
private static Drawable ImageOperations(Context ctx, String url,
String saveFilename) {
try {
InputStream is = (InputStream) fetch(url);
Drawable d = Drawable.createFromStream(is, "src");
return d;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static Object fetch(String address) throws MalformedURLException,
IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
all is working perfect, except the list view scrolling, its very slow. If I disable the images, the scroll speed smooth-ens , but with the image enabled, it lags alot.
Is there any possible way I can reduce or remove this lagging?
Thanks
You need to do your fetching in the background.
One of the examples you can use :
http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
use this library for downloading images in background and caching..
it won't hurt the UI
https://github.com/koush/UrlImageViewHelper
Are you lazy loading your images? See this question for details.
Related
This question already has answers here:
Android - How to download an image and use it as new resource?
(4 answers)
Closed 9 years ago.
I have got a demo image link :
http://madhabpurps.org/wp-content/uploads/2013/04/28-239x300.jpg
I want to set the image in the background of a layout inside the view holder class:
static class ViewHolder {
TextView txtName;
TextView txtCityState;
RelativeLayout rl;
}
holder.txtName.setText(searchArrayList.get(position).getTitle());
holder.txtCityState.setText(searchArrayList.get(position).getDescription());
I have to set the image from the link here, I have tried this line of code but it's showing error.
holder.rl.setBackgroundResource(searchArrayList.get(position).getImage());
I get answer from here change background image of Framelayout via URL
private Drawable ImageOperations(Context ctx, String url, String saveFilename) {
try {
InputStream is = (InputStream) this.fetch(url);
Drawable d = Drawable.createFromStream(is, saveFilename);
return d;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public Object fetch(String address) throws MalformedURLException,IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
and then you can use it like this
Drawable drw = ImageOperations(this,url,filename)
rl.setBackgroundDrawable(drw);
This should fix. But for general case I recommend another way to solve these problems.
I recommend using a well documented image downloading and caching library. I am using picasso http://square.github.io/picasso/ . Setup it, using library is easy.
Then you can fill an imageview by just writing
Picasso.with(activity)
.load(url)
.fit()
.into(imageView);
use the below code
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
Drawable d = new BitmapDrawable(getResources(),bitmap);
rl.setBackgroundDrawable(dr);
I am a learner and have been working on a home visitor app to get image from a URL of the visitor. Using the following code, which I found online, I was able to load image by adding an intent before the screen and adding a button on the screen saying "See Visitor Image" but now I want that my image should load as soon as the app launches. What changes could I make to do that? Thanks for your help.
OnClickListener getImageBtnOnClick = new OnClickListener() {
public void onClick(View view) {
Context context = view.getContext();
Editable ed = inputUrl.getText();
Drawable image = ImageOperations(context,ed.toString(),"image.jpg");
ImageView imgView = new ImageView(context);
imgView = (ImageView)findViewById(R.id.image1);
imgView.setImageDrawable(image);
}
};
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
inputUrl = ((EditText)findViewById(R.id.imageUrl));
inputUrl.setSingleLine();
inputUrl.setTextSize(11);
Button getImageButton = (Button)findViewById(R.id.getImageButton);
getImageButton.setOnClickListener(getImageBtnOnClick);
}
private Drawable ImageOperations(Context ctx, String url, String saveFilename) {
try {
InputStream is = (InputStream) this.fetch(url);
Drawable d = Drawable.createFromStream(is, "src");
return d;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public Object fetch(String address) throws MalformedURLException,IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
You can make use of SmartImageView, it is a drop-in replacement for Android’s standard ImageView which additionally allows images to be loaded from URLs or the user’s contact address book. Images are cached to memory and to disk for super fast loading.
https://github.com/loopj/android-smart-image-view
Or on OnResume of ur activity start downloading the image form the url as u r doing now in the click listener of button in a separate thread to avoid blocking main UI thread. Once you completed the download you can update the image view using handler from the worker thread.
You can make use of async task also instead of creating your own thread and handler to update UI. for more infor about async task refer following link http://www.vogella.com/articles/AndroidPerformance/article.html
is it possible to specify internet url for ImageSpan and get it shown with TextView? I've tried quite a few versions of
String mockContent = "<img src=\"http://www.google.com/intl/en_com/images/srpr/logo3w.png\">";
myTextView.setText(Html.fromHtml(mockContent), BufferType.SPANNABLE);
but that results in the generic not found image (blueish black bordered square).
Do I have to download the image first, then replace all the urls and so on?
Knowing the new C# is capable of handling such resources, I hoped Android might meet my hopes here.
Using API version 10: 2.3.3.
If you have the image source locally then it should work or else use,
Html.fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)
Returns displayable styled text from the provided HTML string.
Nice example I found on web,
String s = Html.fromHtml(htmlContent, new ImageGetter() {
#Override
public Drawable getDrawable(String source) {
// Code for getting image either by download or using static iamge
Drawable d = null;
try {
InputStream src = imageFetch(source);
d = Drawable.createFromStream(src, "src");
if(d != null){
d.setBounds(0,0,(d.getIntrinsicWidth(),
d.getIntrinsicHeight());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return d;
}
},null);
For more info Html.fromHtml with ImageGetter.
public Object fetch(String address) throws MalformedURLException,
IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
private Drawable ImageOperations(Context ctx, String url) {
try {
InputStream is = (InputStream) this.fetch(url);
Drawable d = Drawable.createFromStream(is, "src");
return d;
} catch (MalformedURLException e) {
return null;
} catch (IOException e) {
return null;
}
catch (Exception e)
{
return null;
}
}
try {
Drawable a =ImageOperations(this,"url"); imgView.setImageDrawable(a);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
This works, but on rare ocasions the app freezes due to a "SocketException: Adress family not supported by protocol". Is there any way to fix this? Thanks
You are trying to Download a File from the UI Thread...(which is why your UI Freezes)
Use a Seperate Thread or AsyncTask so that your UI doesn't Freeze up.
This should solve your problem.
As st0le has pointed out you are trying to do the heavy duty stuff from the UI thread.
All heavy-duty stuff in Android should be done on other worker thread. Because doing it in main thread (or the UI thread) can make your application unresponsive and may be killed as the system is persuaded to think that it has hung.
So you have to do the long running operations in separate thread. For implementing this you can use the concept of Handlers.
I am working on an application that downloads images from a url. The problem is that only some images are being correctly downloaded and others are not.
First off, here is the problem code:
public Bitmap downloadImage(String url) {
HttpClient client = new DefaultHttpClient();
HttpResponse response = null;
try {
response = client.execute(new HttpGet(url));
} catch (ClientProtocolException cpe) {
Log.i(LOG_FILE, "client protocol exception");
return null;
} catch (IOException ioe) {
Log.i(LOG_FILE, "IOE downloading image");
return null;
} catch (Exception e) {
Log.i(LOG_FILE, "Other exception downloading image");
return null;
}
// Convert images from stream to bitmap object
try {
Bitmap image = BitmapFactory.decodeStream(response.getEntity().getContent());
if(image==null)
Log.i(LOG_FILE, "image conversion failed");
return image;
} catch (Exception e) {
Log.i(LOG_FILE, "Other exception while converting image");
return null;
}
}
So what I have is a method that takes the url as a string argument and then downloads the image, converts the HttpResponse stream to a bitmap by means of the BitmapFactory.decodeStream method, and returns it. The problem is that when I am on a slow network connection (almost always 3G rather than Wi-Fi) some images are converted to null--not all of them, only some of them. Using a Wi-Fi connection works perfectly; all the images are downloaded and converted properly.
Does anyone know why this is happening? Or better, how can I fix this? How would I even go about testing to determine the problem? Any help is awesome; thank you!
This is a known issue with the JPEG decoder. There are two solutions. Either you download the entire image in a byte[] array using a ByteInputStream and then decode the array (this is what I do in code.google.com/p/shelves.) Another solution is to create a wrapper InputStream as shown below:
public class PatchInputStream extends FilterInputStream {
public PatchInputStream(InputStream in) {
super(in);
}
public long skip(long n) throws IOException {
long m = 0L;
while (m < n) {
long _m = in.skip(n-m);
if (_m == 0L) break;
m += _m;
}
return m;
}
}
Even with a WiFi connection some bitmaps (in particular .BMPs) will not be decoded. It's just a buggy decoder that can not deal with delays. If you search stackoverflow you will find some other solutions such as wrapping the HTTP stream in a buffered http entity. That works but depending on image size can take up a lot of memory. For our commerical product we ended up downloading the http stream to sdcard and then using Bitmapfactory on the dowloaded file. It's somewhat slower but 100% reliable.