0

I'm solving my problem about Image Loader and I have some problems..

  1. What I want is to show many images (about 400) in GridView(or ListView).
  2. I don't want to use the Library like Picasso, Glide like that.

and Here is the problem.

  1. When I call the method which convert from url to bitmap?
    3.1. before setAdapter, then pass the bitmap array.
    3.2. while getView.

  2. two things are working well. but too much slow... maybe cuz of the times to call URLConnection..

Could anyone help me about these problem? How can I speed up? or are there any other solution without Open Source.

Here is my Source.

Now, 3-1.

ShowImage

private void showImages(ArrayList<String> imgUrls) {
    ArrayList<Bitmap> bitmaps = new ArrayList<>();
    for (int i = 0; i < imgUrls.size(); i++) {
        try {
            String img_path = imgUrls.get(i);
            Bitmap bitmap = new UriToBitmapAsyncTask().execute(img_path).get();
            bitmaps.add(bitmap);
        } catch (Exception e) {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
    CustomAdapter adapter = new CustomAdapter(getApplicationContext(),R.layout.row,bitmaps);

    gridView.setAdapter(adapter);
}

and This is the customAdapter's GetView

 public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;

    if (convertView == null) {
        convertView = inflator.inflate(rowLayout, parent, false);

        viewHolder = new ViewHolder();
        viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.imageView.setImageBitmap(bitmaps.get(position));
    return convertView;
}
ColdFire
  • 6,764
  • 6
  • 35
  • 51
Adrian
  • 301
  • 4
  • 15
  • You have to load all the image by Glide or Picasso. Why you are taking bitmap from URL ? – Rujul Gandhi Apr 11 '18 at 09:37
  • *How can I speed up?* - use one of those image loading libraries you don't want to use, instead of sequentially fetching all images on the same thread – Tim Apr 11 '18 at 09:41
  • @Rujul Gandhi I know the library make me comfortable. but This is the project and One of important is that anyone haven't to use the Library lile Glide or Picasso.. so that's the problem to me.. – Adrian Apr 11 '18 at 09:45
  • Have you added Glide dependency into your project ? – Rujul Gandhi Apr 11 '18 at 09:48
  • @Rujul Gandhi yep. I added Picasso.and working very well even the speed is nice. but What I want is to mke the project sithoit any Library.. – Adrian Apr 11 '18 at 09:52
  • I don't see a single reason why you can't use ready-made library. – Vladyslav Matviienko Apr 11 '18 at 09:59

2 Answers2

0

You should really take Reinventing the wheel to heart but if you really want to toture yourself an Approach could be:

  1. use a ThreadPoolExecutor to fetch more images at once, you should read up how to use them
  2. implement a way to cancel threads who load a img for a griditem which isn't displayed anymore
  3. use two sets of data a thumbnail which loads faster for the grid view and a real image which gets loaded when the user clicks on the grid
  4. dont't forget to use a LRU caching method or your device will run out of memory depending on the images
Rüdiger
  • 1,674
  • 1
  • 20
  • 28
0

Don't use ArrayList to store bitmaps. Bitmaps usually take consumes a lot of memory. Try using LRUCache like this way,

public class TCImageLoader implements ComponentCallbacks2 {
private TCLruCache cache;

public TCImageLoader(Context context) {
    ActivityManager am = (ActivityManager) context.getSystemService(
        Context.ACTIVITY_SERVICE);
    int maxKb = am.getMemoryClass() * 1024;
    int limitKb = maxKb / 8; // 1/8th of total ram
    cache = new TCLruCache(limitKb);
}

public void display(String url, ImageView imageview, int defaultresource) {
    imageview.setImageResource(defaultresource);
    Bitmap image = cache.get(url);
    if (image != null) {
        imageview.setImageBitmap(image);
    }
    else {
        new SetImageTask(imageview).execute(url);
    }
}

private class TCLruCache extends LruCache<String, Bitmap> {

    public TCLruCache(int maxSize) {
        super(maxSize);
    }

    @Override
    protected int sizeOf(ImagePoolKey key, Bitmap value) {
        int kbOfBitmap = value.getByteCount() / 1024;
        return kbOfBitmap;
    }
}

private class SetImageTask extends AsyncTask<String, Void, Integer> {
    private ImageView imageview;
    private Bitmap bmp;

    public SetImageTask(ImageView imageview) {
        this.imageview = imageview;
    }

    @Override
    protected Integer doInBackground(String... params) {
        String url = params[0];
        try {
            bmp = getBitmapFromURL(url);
            if (bmp != null) {
                cache.put(url, bmp);
            }
            else {
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        return 1;
    }

    @Override
    protected void onPostExecute(Integer result) {
        if (result == 1) {
            imageview.setImageBitmap(bmp);
        }
        super.onPostExecute(result);
    }

    private Bitmap getBitmapFromURL(String src) {
        try {
            URL url = new URL(src);
            HttpURLConnection connection
                = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
}

@Override
public void onLowMemory() {
}

@Override
public void onTrimMemory(int level) {
    if (level >= TRIM_MEMORY_MODERATE) {
        cache.evictAll();
    }
    else if (level >= TRIM_MEMORY_BACKGROUND) {
        cache.trimToSize(cache.size() / 2);
    }
}
}

get a instance of TCImageLoader and call display method appropriately.

VivekRajendran
  • 676
  • 1
  • 6
  • 21