Note that there are some explanatory texts on larger screens.

plurals
  1. POandroid lazy loading not showing images on phone or showing and is slow
    primarykey
    data
    text
    <p>I am using JSON to parse an online xml document and also 2 methods for lazy image loading. Below is my source code, explanation and my problem:</p> <p>Explanation:</p> <p>Method 1: Use <code>AsyncTask</code> and line <code>imageLoader.DisplayImage((String)jsonImageText.get("imageLink"), activity, imageView);</code> inside the adapter.</p> <p>Method 2:</p> <p>Not use <code>AsyncTask</code> and use the rest of the try-catch block and NOT the line <code>imageLoader.DisplayImage((String)jsonImageText.get("imageLink"), activity, imageView);</code></p> <p>The problems:</p> <p>Method 1: </p> <p>The images are displayed on the emulator and the loading is pretty fast, but they fail to display on a phone or a tablet.</p> <p>Method 2:</p> <p>The images are displayed on all the emulators and real devices, but the loading and scrolling are very slow.</p> <p>Is there any way to fix either of these 2 methods or even both?</p> <p>This is the list adapter which returns the ListView's row view:</p> <pre><code>public class RssListAdapter extends ArrayAdapter&lt;JSONObject&gt; { public ImageLoader imageLoader; public RssListAdapter(Activity activity, List&lt;JSONObject&gt; imageAndTexts) { super(activity, 0, imageAndTexts); imageLoader=new ImageLoader(activity.getApplicationContext()); } @Override public View getView(int position, View convertView, ViewGroup parent) { Activity activity = (Activity) getContext(); LayoutInflater inflater = activity.getLayoutInflater(); // Inflate the views from XML View rowView = inflater.inflate(R.layout.image_text_layout, null); JSONObject jsonImageText = getItem(position); TextView textView = (TextView) rowView.findViewById(R.id.job_text); ImageView imageView = (ImageView) rowView.findViewById(R.id.feed_image); try { if (jsonImageText.get("imageLink") != null){ System.out.println("XXXX Link found!"); String url = (String) jsonImageText.get("imageLink"); URL feedImage= new URL(url); HttpURLConnection conn= (HttpURLConnection)feedImage.openConnection(); InputStream is = conn.getInputStream(); Bitmap img = BitmapFactory.decodeStream(is); imageView.setImageBitmap(img); //imageLoader.DisplayImage((String)jsonImageText.get("imageLink"), activity, imageView); } Spanned text = (Spanned)jsonImageText.get("text"); textView.setText(text); } catch (MalformedURLException e) { textView.setText("JSON Exception"); } catch (IOException e) { textView.setText("JSON Exception"); } catch (JSONException e) { textView.setText("JSON Exception"); } return rowView; } } </code></pre> <p>This is the ImageLoader class:</p> <pre><code>public class ImageLoader { MemoryCache memoryCache=new MemoryCache(); FileCache fileCache; private Map&lt;ImageView, String&gt; imageViews=Collections.synchronizedMap(new WeakHashMap&lt;ImageView, String&gt;()); public ImageLoader(Context context){ //Make the background thread low priority. This way it will not affect the UI performance photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1); fileCache=new FileCache(context); } final int stub_id=R.drawable.icon; public void DisplayImage(String url, Activity activity, ImageView imageView) { imageViews.put(imageView, url); Bitmap bitmap=memoryCache.get(url); if(bitmap!=null) imageView.setImageBitmap(bitmap); else { queuePhoto(url, activity, imageView); imageView.setImageResource(stub_id); } } private void queuePhoto(String url, Activity activity, ImageView imageView) { //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. photosQueue.Clean(imageView); PhotoToLoad p=new PhotoToLoad(url, imageView); synchronized(photosQueue.photosToLoad){ photosQueue.photosToLoad.push(p); photosQueue.photosToLoad.notifyAll(); } //start thread if it's not started yet if(photoLoaderThread.getState()==Thread.State.NEW) photoLoaderThread.start(); } private Bitmap getBitmap(String url) { File f=fileCache.getFile(url); //from SD cache Bitmap b = decodeFile(f); if(b!=null) return b; //from web try { Bitmap bitmap=null; URL imageUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); InputStream is=conn.getInputStream(); OutputStream os = new FileOutputStream(f); Utils.CopyStream(is, os); os.close(); bitmap = decodeFile(f); return bitmap; } catch (Exception ex){ ex.printStackTrace(); return null; } } //decodes image and scales it to reduce memory consumption private Bitmap decodeFile(File f){ try { //decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(f),null,o); //Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE=70; int width_tmp=o.outWidth, height_tmp=o.outHeight; int scale=1; while(true){ if(width_tmp/2&lt;REQUIRED_SIZE || height_tmp/2&lt;REQUIRED_SIZE) break; width_tmp/=2; height_tmp/=2; scale*=2; } //decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) {} return null; } //Task for the queue private class PhotoToLoad { public String url; public ImageView imageView; public PhotoToLoad(String u, ImageView i){ url=u; imageView=i; } } PhotosQueue photosQueue=new PhotosQueue(); public void stopThread() { photoLoaderThread.interrupt(); } //stores list of photos to download class PhotosQueue { private Stack&lt;PhotoToLoad&gt; photosToLoad=new Stack&lt;PhotoToLoad&gt;(); //removes all instances of this ImageView public void Clean(ImageView image) { for(int j=0 ;j&lt;photosToLoad.size();){ if(photosToLoad.get(j).imageView==image) photosToLoad.remove(j); else ++j; } } } class PhotosLoader extends Thread { public void run() { try { while(true) { //thread waits until there are any images to load in the queue if(photosQueue.photosToLoad.size()==0) synchronized(photosQueue.photosToLoad){ photosQueue.photosToLoad.wait(); } if(photosQueue.photosToLoad.size()!=0) { PhotoToLoad photoToLoad; synchronized(photosQueue.photosToLoad){ photoToLoad=photosQueue.photosToLoad.pop(); } Bitmap bmp=getBitmap(photoToLoad.url); memoryCache.put(photoToLoad.url, bmp); String tag=imageViews.get(photoToLoad.imageView); if(tag!=null &amp;&amp; tag.equals(photoToLoad.url)){ BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView); Activity a=(Activity)photoToLoad.imageView.getContext(); a.runOnUiThread(bd); } } if(Thread.interrupted()) break; } } catch (InterruptedException e) { //allow thread to exit } } } PhotosLoader photoLoaderThread=new PhotosLoader(); //Used to display bitmap in the UI thread class BitmapDisplayer implements Runnable { Bitmap bitmap; ImageView imageView; public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;} public void run() { if(bitmap!=null) imageView.setImageBitmap(bitmap); else imageView.setImageResource(stub_id); } } public void clearCache() { memoryCache.clear(); fileCache.clear(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload