GridView scroll slow, heavy,

0

I'm trying to create an app that is sort of a gallery. Search for photos on your phone and show it to the user.

The app is already working, but it happens that the gridview scroll is slow.

I do not know what to do to try to improve performance. I'm using LruCache to store the images, the images are loaded asynchronously.

I put all the codes that I think are pertinent.

GridAdapter

package abcde.xyz;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

import java.util.ArrayList;

/**
 * Created by Lucas on 25/03/2017.
 */

public class GridImagesAdapter extends ArrayAdapter {


    private Context context;
    private int layoutResourceId;
    private ArrayList data = new ArrayList();
    public static LruCache<Integer, Bitmap> mMemoryCache;

    public GridImagesAdapter(Context context, int layoutResourceId, ArrayList<Integer> data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;


        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

        final int cacheSize = maxMemory / 4;
        if(mMemoryCache == null){
            mMemoryCache = new LruCache<Integer, Bitmap>(cacheSize) {
                @Override
                protected int sizeOf(Integer key, Bitmap bitmap) {
                    return bitmap.getByteCount() / 1024;
                }
            };
        }
        mMemoryCache.evictAll();

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            ImageView image = (ImageView)row.findViewById(R.id.image);
            final Integer item = (Integer)data.get(position);


            image.setImageBitmap(null);
            ImageGridHandler handler = new ImageGridHandler(context, image);
            handler.execute(item);
        }

        return row;
    }
}

ImageGridHandler

package abcde.xyz;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.ImageView;

import java.lang.ref.WeakReference;

/**
 * Created by Lucas on 29/03/2017.
 */

public class ImageGridHandler extends AsyncTask<Integer, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private Context context;
    public ImageGridHandler(Context context, ImageView img){
        imageViewReference = new WeakReference<ImageView>(img);
        this.context = context;
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {

        return loadBitmap(params[0]);

    }

    @Override
    protected void onPostExecute(Bitmap result) {
        final ImageView imageView = imageViewReference.get();

        if(imageView != null) {
            //imageView.setScaleType(ImageView.ScaleType.CENTER);
            imageView.setImageBitmap(result);
        }
    }


    public void addBitmapToMemoryCache(Integer key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            GridImagesAdapter.mMemoryCache.put(key, bitmap);
        }
    }

    public Bitmap getBitmapFromMemCache(Integer key) {
        return GridImagesAdapter.mMemoryCache.get(key);
    }

    public Bitmap loadBitmap(Integer resId) {


        Bitmap bitmap = getBitmapFromMemCache(resId);
        if (bitmap == null) {

           Log.d("ImageGridHandler", "Loading: " + resId);
            if(resId != null) {
                bitmap = MediaStore.Images.Thumbnails.getThumbnail(
                        context.getContentResolver(), resId,
                        MediaStore.Images.Thumbnails.MICRO_KIND,
                        null);
                if(bitmap != null) {
                    addBitmapToMemoryCache(resId, bitmap);
                }
            }

            Log.d("GRIDADAPTER", "ImageLoaded");
        }

        return bitmap;
    }


}

Layouts

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="umdev.images24.MainActivity"
    tools:showIn="@layout/activity_main">
    <android.support.v4.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swipeRefresh"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        tools:layout_editor_absoluteY="8dp"
        tools:layout_editor_absoluteX="8dp">

     <GridView
         android:id="@+id/gridView"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_margin="0dp"
         android:drawSelectorOnTop="true"
         android:gravity="center"
         android:columnWidth="100dp"
         android:numColumns="auto_fit"
         android:stretchMode="columnWidth"
         android:verticalSpacing="0dp"
         android:focusable="true"
         android:clickable="true"
         android:fastScrollEnabled="true"/>

    </android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>

grid_item_layout.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="2dp"
    android:background="#fff">

    <ImageView
        android:id="@+id/image"
        android:layout_width="120dp"
        android:layout_height="120dp" />

</LinearLayout>
    
asked by anonymous 30.03.2017 / 13:11

2 answers

2

The android has few features to display images (which are usually heavy). To resolve this problem, you must use an image-processing library (to save work for you). An example is Glide . The library manages all image caching / processing / download automatically.

At the time of linking the image in the imageView through its methods

 image.setImageBitmap(null);
 ImageGridHandler handler = new ImageGridHandler(context, image);
 handler.execute(item); , 

You should use

Glide.with(meuContexto).load(minhaImagem).into(image);

where the variable "myImage" can be a url, a resource or a bitmap.

    
30.03.2017 / 14:31
0

The problem was loading an image larger than ImageView. In this case ImageView had to make a change of the image size always.

Load Scaled Down Version into Memory

link

    
31.03.2017 / 01:50