Note that there are some explanatory texts on larger screens.

plurals
  1. POblack screen appears when data loading takes long time in android
    text
    copied!<p>onCreateMethod of a Base class:</p> <pre><code>setListAdapter(new EfficientAdapter(this)); </code></pre> <p>Efficient Base Adapter class:</p> <pre><code> private class EfficientAdapter extends BaseAdapter { private LayoutInflater mInflater; Friends obj; Friends object; FriendsPictures pictureObject; ArrayList&lt;FriendsPictures&gt; arrayFriendsPictures; public EfficientAdapter(Context context) { // Cache the LayoutInflate to avoid asking for a new one each time. mInflater = LayoutInflater.from(context); } /** * The number of items in the list is determined by the number of speeches * in our array. * * @see android.widget.ListAdapter#getCount() */ public int getCount() { return arrFriendsObject.size(); } /** * Since the data comes from an array, just returning the index is * sufficent to get at the data. If we were using a more complex data * structure, we would return whatever object represents one row in the * list. * * @see android.widget.ListAdapter#getItem(int) */ public Object getItem(int position) { return position; } /** * Use the array index as a unique id. * * @see android.widget.ListAdapter#getItemId(int) */ public long getItemId(int position) { return position; } private final ImageDownloader imageDownloader = new ImageDownloader(); // private final DrawableManager drawable= new DrawableManager(); /** * Make a view to hold each row. * * @see android.widget.ListAdapter#getView(int, android.view.View, * android.view.ViewGroup) */ public View getView(int position, View convertView, ViewGroup parent) { // A ViewHolder keeps references to children views to avoid unneccessary calls // to findViewById() on each row. final ViewHolder holder; obj = arrFriendsObject.get(position); // When convertView is not null, we can reuse it directly, there is no need // to reinflate it. We only inflate a new View when the convertView supplied // by ListView is null. if (convertView == null) { convertView = mInflater.inflate(R.layout.Friendslistview, null); // Creates a ViewHolder and store references to the two children views // we want to bind data to. holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.FriendsText); holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { // Get the ViewHolder back to get fast access to the TextView // and the ImageView. holder = (ViewHolder) convertView.getTag(); } // Bind the data efficiently with the holder. holder.text.setText(obj.FriendsTitle); // holder.icon.setImageBitmap((position &amp; 1) == 1 ? mIcon1 : mIcon2); // _mLoadImage = new GetImageAsyncTask(); // _mLoadImage.execute(urls[position]); object = new Friends(); object = arrFriendsObject.get(position); arrayFriendsPictures = new ArrayList&lt;FriendsPictures&gt;(); pictureObject = new FriendsPictures(); arrayFriendsPictures = object.arrFriendsPictures; pictureObject = arrayFriendsPictures.get(0); if(pictureObject.Image == null){ pictureObject.Image = imageDownloader.download(pictureObject.ImageUrl, (ImageView) holder.icon); // pictureObject.Image = drawable.fetchDrawableOnThread(pictureObject.ImageUrl, (ImageView) holder.icon); object.arrFriendsPictures.set(0,pictureObject); arrFriendsObject.set(position, object); } else { holder.icon.setImageBitmap(arrFriendsObject.get(position).arrFriendsPictures.get(0).Image); } // holder.icon.setBackgroundResource(R.drawable.photo1); convertView.setOnClickListener(mShowDetails); return convertView; } class ViewHolder { TextView text; ImageView icon; // ProgressBar showProgress; } } </code></pre> <p>ImageDownloader class:</p> <pre><code>public class ImageDownloader { private ProgressDialog dialog; private static final String LOG_TAG = "ImageDownloader"; public Bitmap download(String url, ImageView imageView) { resetPurgeTimer(); Bitmap bitmap = getBitmapFromCache(url); if (bitmap == null) { bitmap = forceDownload(url, imageView); } else { cancelPotentialDownload(url, imageView); imageView.setImageBitmap(bitmap); } return bitmap; } private Bitmap forceDownload(String url, ImageView imageView) { Bitmap bitmap = null; // State sanity: url is guaranteed to never be null in DownloadedDrawable and cache keys. if (url == null) { imageView.setImageDrawable(null); return null; } if (cancelPotentialDownload(url, imageView)) { BitmapDownloaderTask task = new BitmapDownloaderTask(imageView); DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task); imageView.setImageDrawable(downloadedDrawable); imageView.setMinimumHeight(156); task.execute(url); try { bitmap = task.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return bitmap; } private static boolean cancelPotentialDownload(String url, ImageView imageView) { BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); if (bitmapDownloaderTask != null) { String bitmapUrl = bitmapDownloaderTask.url; if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) { bitmapDownloaderTask.cancel(true); } else { // The same URL is already being downloaded. return false; } } return true; } private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) { if (imageView != null) { Drawable drawable = imageView.getDrawable(); if (drawable instanceof DownloadedDrawable) { DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable; return downloadedDrawable.getBitmapDownloaderTask(); } } return null; } Bitmap downloadBitmap(String url) { final int IO_BUFFER_SIZE = 4 * 1024; // AndroidHttpClient is not allowed to be used from the main thread final HttpClient client = new DefaultHttpClient(); final HttpGet getRequest = new HttpGet(url); try { HttpResponse response = client.execute(getRequest); final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); return null; } final HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inputStream = null; try { inputStream = entity.getContent(); // return BitmapFactory.decodeStream(inputStream); // Bug on slow connections, fixed in future release. return BitmapFactory.decodeStream(new FlushedInputStream(inputStream)); } finally { if (inputStream != null) { inputStream.close(); } entity.consumeContent(); } } } catch (IOException e) { getRequest.abort(); Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e); } catch (IllegalStateException e) { getRequest.abort(); Log.w(LOG_TAG, "Incorrect URL: " + url); } catch (Exception e) { getRequest.abort(); Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e); } finally { } return null; } static class FlushedInputStream extends FilterInputStream { public FlushedInputStream(InputStream inputStream) { super(inputStream); } @Override public long skip(long n) throws IOException { long totalBytesSkipped = 0L; while (totalBytesSkipped &lt; n) { long bytesSkipped = in.skip(n - totalBytesSkipped); if (bytesSkipped == 0L) { int b = read(); if (b &lt; 0) { break; // we reached EOF } else { bytesSkipped = 1; // we read one byte } } totalBytesSkipped += bytesSkipped; } return totalBytesSkipped; } } public class BitmapDownloaderTask extends AsyncTask&lt;String, Void, Bitmap&gt; { private String url; Bitmap bitmap; private final WeakReference&lt;ImageView&gt; imageViewReference; public BitmapDownloaderTask(ImageView imageView) { imageViewReference = new WeakReference&lt;ImageView&gt;(imageView); } @Override // can use UI thread here protected void onPreExecute() { if(dialog!=null) { dialog.setMessage("loading.."); dialog.show(); } } @Override protected Bitmap doInBackground(String... params) { url = params[0]; return downloadBitmap(url); } @Override protected void onPostExecute(Bitmap bitmap) { if (isCancelled()) { bitmap = null; } if(dialog!=null) { dialog.dismiss(); } addBitmapToCache(url, bitmap); if (imageViewReference != null) { ImageView imageView = imageViewReference.get(); BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); // Change bitmap only if this process is still associated with it // Or if we don't use any bitmap to task association (NO_DOWNLOADED_DRAWABLE mode) if ((this == bitmapDownloaderTask)) { imageView.setImageBitmap(bitmap); } } } } static class DownloadedDrawable extends ColorDrawable { private final WeakReference&lt;BitmapDownloaderTask&gt; bitmapDownloaderTaskReference; public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) { super(Color.BLACK); bitmapDownloaderTaskReference = new WeakReference&lt;BitmapDownloaderTask&gt;(bitmapDownloaderTask); } public BitmapDownloaderTask getBitmapDownloaderTask() { return bitmapDownloaderTaskReference.get(); } } private static final int HARD_CACHE_CAPACITY = 10; private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds // Hard cache, with a fixed maximum capacity and a life duration private final HashMap&lt;String, Bitmap&gt; sHardBitmapCache = new LinkedHashMap&lt;String, Bitmap&gt;(HARD_CACHE_CAPACITY / 2, 0.75f, true) { @Override protected boolean removeEldestEntry(LinkedHashMap.Entry&lt;String, Bitmap&gt; eldest) { if (size() &gt; HARD_CACHE_CAPACITY) { // Entries push-out of hard reference cache are transferred to soft reference cache sSoftBitmapCache.put(eldest.getKey(), new SoftReference&lt;Bitmap&gt;(eldest.getValue())); return true; } else return false; } }; // Soft cache for bitmaps kicked out of hard cache private final static ConcurrentHashMap&lt;String, SoftReference&lt;Bitmap&gt;&gt; sSoftBitmapCache = new ConcurrentHashMap&lt;String, SoftReference&lt;Bitmap&gt;&gt;(HARD_CACHE_CAPACITY / 2); private final Handler purgeHandler = new Handler(); private final Runnable purger = new Runnable() { public void run() { clearCache(); } }; private void addBitmapToCache(String url, Bitmap bitmap) { if (bitmap != null) { synchronized (sHardBitmapCache) { sHardBitmapCache.put(url, bitmap); } } } private Bitmap getBitmapFromCache(String url) { // First try the hard reference cache synchronized (sHardBitmapCache) { final Bitmap bitmap = sHardBitmapCache.get(url); if (bitmap != null) { // Bitmap found in hard cache // Move element to first position, so that it is removed last sHardBitmapCache.remove(url); sHardBitmapCache.put(url, bitmap); return bitmap; } } // Then try the soft reference cache SoftReference&lt;Bitmap&gt; bitmapReference = sSoftBitmapCache.get(url); if (bitmapReference != null) { final Bitmap bitmap = bitmapReference.get(); if (bitmap != null) { // Bitmap found in soft cache return bitmap; } else { // Soft reference has been Garbage Collected sSoftBitmapCache.remove(url); } } return null; } public void clearCache() { sHardBitmapCache.clear(); sSoftBitmapCache.clear(); } private void resetPurgeTimer() { purgeHandler.removeCallbacks(purger); purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE); } } </code></pre>
 

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