I'm having trouble with my listviews items. I'm dynamically getting some images from a XML file, downloading the image and setting it.
I'm trying to primitively cache the bitmap fetched to speed up the getView process of my listviews adapter. But when trying to scroll my listview the phone seems to 'lag'.
This is the part of my code which is responsible for the 'lag':
if( ni.Bitmap == null )
{
Pattern p = Pattern.compile("<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>");
Matcher m = p.matcher(ni.Description);
boolean result = m.find();
if( result )
{
try {
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(m.group(1)).getContent());
ni.Bitmap = bitmap;
holder.theimage.setImageBitmap(ni.Bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
else
holder.theimage.setImageBitmap(ni.Bitmap);
Can I in anyway speed up this process?
Check this Url. you will get lot thing about this.
https://stackoverflow.com/search?q=lazy+loading+listview+android
Related
How can I list all files, recursively in DropBox folder?
I tried code below but returns no result:
result = dbxClient.files().search("", "*");
And this returns files in path, not subfolders:
result = dbxClient.files().listFolder(path);
You can get a ListFolderBuilder from listFolderBuilder and use the withRecursive option to list out sub-items as well.
Be sure to check ListFolderResult.hasMore to see if you should call back to listFolderContinue to get more results though.
You can check this link, navigate to inner class 'FolderScanTask'. It contains working code for Android:
https://github.com/ControlX/Android-Dropbox-UploadImage-To-SpecificFolder-By-FolderSelection/blob/master/app/src/main/java/io/github/controlx/dbxdemo/MainActivity.java
This is work in progress, here I'm just making an ArrayList for parent folders, has more logic as suggested by Greg is already there you just need to fill in that.
Code Snippet for the same:
String path = "";
DbxClientV2 dbxClient = DropboxClient.getClient(ACCESS_TOKEN);
TreeMap<String, Metadata> children = new TreeMap<String, Metadata>();
try {
try {
result = dbxClient.files()
.listFolder(path);
} catch (ListFolderErrorException ex) {
ex.printStackTrace();
}
List<Metadata> list = result.getEntries();
cs = new CharSequence[list.size()];
arrayList = new ArrayList<>();
arrayList.add("/");
while (true) {
int i = 0;
for (Metadata md : result.getEntries()) {
if (md instanceof DeletedMetadata) {
children.remove(md.getPathLower());
} else {
String fileOrFolder = md.getPathLower();
children.put(fileOrFolder, md);
if(!fileOrFolder.contains("."))
arrayList.add(fileOrFolder);
}
i++;
}
if (!result.getHasMore()) break;
try {
result = dbxClient.files()
.listFolderContinue(result.getCursor());
} catch (ListFolderContinueErrorException ex) {
ex.printStackTrace();
}
}
} catch (DbxException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Here ArrayList is just for my use wherein I'm just making a list of only folders.
So, modify accordingly.
I want to get Image from cache memory, I am using volley library and displaying image successfully. I want to get same downloaded image from cache Below is my code.
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Entry entry = cache.get(ImageUrl);
if (entry != null) {
try {
// Get Data From Catch Successefully
String data = new String(entry.data, "UTF-8");
// but now this code return null value i want Bitmap From Catch
LruBitmapCache bitmapCache = new LruBitmapCache();
mBitmap = bitmapCache.getBitmap(data);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
I can get data from cache, but bitmapCache.getBitmap(data); return's null.
use this line instead to convert entry.data into bitmap:
mBitmap = BitmapFactory.decodeByteArray(entry.data, 0, entry.data.length);
So my issue is exactly as the title states. I am downloading many different images and scaling them then setting them to a view. My issue is it seems that only .gif images are visible in the views that are created and the views that should contain .jpg images are almost blank. I say almost because there seems to be a strange tiny black dot on each .jpg view of different shapes, and by tiny I mean the size of a period, so those might be the images but reduced in size too much. Any help... p.s Though outputs I am sure the images are going though my bitmap and makeing it to the setImageBitmap().
My bitmap creating method:
#Override
protected Bitmap doInBackground(String... url) {
String url1 = url[0];
InputStream s = null;
try {
s = (new URL(url1)).openStream();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final BufferedInputStream is = new BufferedInputStream(s, 32*1024);
try {
final Options decodeBitmapOptions = new Options();
// For further memory savings, you may want to consider using this option
// decodeBitmapOptions.inPreferredConfig = Config.RGB_565; // Uses 2-bytes instead of default 4 per pixel
if( parent.getResources().getDisplayMetrics().widthPixels >0) {
final Options decodeBoundsOptions = new Options();
decodeBoundsOptions.inJustDecodeBounds = true;
is.mark(32*1024); // 32k is probably overkill, but 8k is insufficient for some jpgs
BitmapFactory.decodeStream(is,null,decodeBoundsOptions);
is.reset();
final int originalWidth = decodeBoundsOptions.outWidth;
final int originalHeight = decodeBoundsOptions.outHeight;
Debug.out("Inbound image preview for : "+url1);
Debug.out(originalWidth);
Debug.out(originalHeight);
// inSampleSize prefers multiples of 2, but we prefer to prioritize memory savings
decodeBitmapOptions.inSampleSize= Math.max(1,Math.min(originalWidth / 2, originalHeight / 2));
}
return BitmapFactory.decodeStream(is,null,decodeBitmapOptions);
} catch( IOException e ) {
throw new RuntimeException(e); // this shouldn't happen
} finally {
try {
is.close();
} catch( IOException ignored ) {}
}
}
Also here is where I set my new image after download :
protected void onPostExecute(Bitmap map) {
//image is a object of type ImageView that has already been added to to the grand scheme of things
image.setImageBitmap(map);
}
Do I need to update the view or something? If so why do my gifs load fine?
Issue turned out to be with my scaling, particularly this line decodeBitmapOptions.inSampleSize= Math.max(1,Math.min(originalWidth / 2, originalHeight / 2));
I am downloading the image from website and attach into listview.
URL aURL;
try {
aURL = new URL(//"http://www.orientaldaily.com.my/"+
imagepath[i]);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Bitmap bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
imageview = (ImageView) findViewById(R.id.image_alllatestnewstitle);
imageview.setVisibility(View.VISIBLE);
imageview.setScaleType(ScaleType.CENTER_CROP);
imageview.setImageBitmap(bm);
} catch (IOException e) {
Log.e("DEBUGTAG", "Remote Image Exception", e);
}
When i downloading only 1 image, it got no problem, however when i downloading multiple or more than 5 images and load into listview, it cause problem.
The problem was
bitmap size exceeds VM budget
How to avoid this problem?
Note: this is not duplicate any question!
Thanks.
Load lot many images causes the app to run out of memory and force closes.I think this is what happening to your application.the memory issue is a complex issue android while developing an application.this can be solved by manually clearing the unused bitmaps and by using the garbage collector.
Try using System.gc();
Try recycling the bitmap using
Bitmap.recycle();
Make all the unused bitmap null.
Deallocate all the unused memory.
This all will help you a lot and also go through this link.Use memory analyzer it will help you spot out the Deallocated memory>try this link
public void deAllocateAllMemory()
{
try
{
mGallery.imgLoader1.disposeImages();
unbindDrawables(findViewById(R.id.magazineGrid));
mGallery=null;
back.getBackground().setCallback(null);
back.setOnClickListener(null);
store.getBackground().setCallback(null);
store.setOnClickListener(null);
quickAction.setOnActionItemClickListener(null);
settings.getBackground().setCallback(null);
settings.setOnClickListener(null);
}
catch (Exception e)
{
}
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
try {
view.getBackground().setCallback(null);
((BitmapDrawable) view.getBackground()).getBitmap().recycle();
view.destroyDrawingCache();
view.notifyAll();
} catch (Exception e) {
}
}
This piece of code may help you a lil bit.
Displaying Bitmaps Efficiently tutorial could help you.
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.