Good image resolution causes "OutOfMemoryError"

8

I have a question about how I can work with good resolution images, because when I put them on I slow down the application, I would like to know if there is a way to work with an acceptable resolution without affecting the speed of the application. For example, a gallery of images that as I move, the application slows down. Thanks in advance.

public class AdapterAlbum extends RecyclerView.Adapter<AdapterAlbum.ViewHolderClase> {



public class ViewHolderClase extends RecyclerView.ViewHolder {

    ImageView imageView;

    public ViewHolderClase(View itemView) {

        super(itemView);
        imageView = (ImageView) itemView.findViewById(R.id.cover);
    }
}

@Override
public ViewHolderClase onCreateViewHolder(ViewGroup parent, int viewType) {
    View viewItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.album, null);
    return new ViewHolderClase(viewItem);
}

@Override
public void onBindViewHolder(final ViewHolderClase holder, int position) {
    holder.imageView.setBackgroundResource(Activity.imagenes.get(position));


}

@Override
public int getItemCount() {
    return Activity.imagenes.size();
}

} good in itself the design where I load the images is simple, cave highlight that my images are approximately 43.4k for having a little more resolution

Activity:

    public class Actividad {

    RecyclerView recyclerView;
    RecyclerView.Adapter adapter;
    RecyclerView.LayoutManager layoutManager;
    static ArrayList<Integer> imagenes;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        imagenes = new ArrayList<>();
        imagenes.addAll(Arrays.asList(R.drawable.cold22, R.drawable.cover3, R.drawable.coverr,
                R.drawable.cover6, R.drawable.cold3, R.drawable.cover4, R.drawable.cover87, R.drawable.cover12));
        contentView = inflater.inflate(R.layout.activ, null);
        return contentView;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onCreated(Bundle savedInstanceState) {
        super.onCreated(savedInstanceState);
        recyclerView = (RecyclerView) contentView.findViewById(R.id.reyclerViewTres);
        layoutManager = new GridLayoutManager(getActivity(), 2);
        recyclerView.setLayoutManager(layoutManager);

        adapter = new AdapterAlbum();
        recyclerView.setAdapter(adapter);

    }

}
    
asked by Gunnar 26.03.2016 в 11:39
source

4 answers

9

This is a good question, what is the measure that images should have in an application so that it does not consume a lot of memory and therefore be slow?

Actually the answer is that they must be of an acceptable resolution but a weight in small kbs (something similar to images used in web pages), this to avoid mainly within the application processing and manipulation in memory of the image and consumption of bandwidth that might be unnecessary.

How to make your image light, well you can work with the compression in bytes.

Here is a tutorial: link

The Android SDK has a way to optimize the loading of images, which involves taking a smaller image format by means of the class BitmapFactory :

link

Other recommended considering a previous optimization of the images are the use of two libraries mainly,

GLIDE and PICASSO , whose implementation is simple and very similar.

There are other options but making a benchmark in my opinion are the best options.

Regarding your problem:

  

gallery of images that as I move I get slow the   application.

You must ensure that the image is evicted from the ImageView so that the Garbage Collector can eliminate it from memory, this when it is no longer visible on the screen, because if they are accumulating you could have after a certain time a Java.Lang.OutOfMemoryError , you can do it with:

miImageView.setBackgroundDrawable(null) 

or

miImageView.setImageDrawable(null);
    
answered by 26.03.2016 / 19:42
source
5

I advise you to use some of the 3 famous frameworks for these tasks, and remember that many of these tasks require certain permissions. My recommendation is Glide for images and Volley for everything else.

  

Picasso , ideal for high-resolution images: Link

Picasso.with(context).load(address).into(imageView);
  

Glide , ideal for images of accepted resolutions: Link

Glide.with(context).load(address).into(imageView);
  

Volley , ideal for GET / POST data transmission, accepts JSON: Link

ImageView imageView = new ImageView(context);
ImageLoader imageLoader = new ImageLoader(Volley.newRequestQueue(context), new BitmapLruCache());

<com.android.volley.toolbox.NetworkImageView
    android:id="@+id/imgAvatar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"/>

NetworkImageView imgAvatar = (NetworkImageView) findViewById(R.id.imgAvatar);
imageView.setImageUrl(url, imageLoader);
    
answered by 26.03.2016 в 13:34
1

Load the image when it is going to be used and delete it when not, if you upload images but do not delete them, your application will consume more memory every time. On the other hand, I advise you to use images with a resolution according to the application, and if it is not feasible resize it.

    
answered by 26.03.2016 в 11:52
1

I use the Glide library to load images in a viewImage , it is responsible for properly dimensioning them for the device and saving them in the cache to speed up the process later. Test to see if you still have a performance problem.

    
answered by 26.03.2016 в 12:59