This is very common. And, in addition to slowness, you can catch the famous exception OutOffMemory
.
To avoid this, you can solve in two (simple) steps inside your adapter:
1) - Place all image uploads within a AsyncTask
. This causes you to pull out of your main thread the job of loading heavy images and blocking the user experience. And, in addition, you can cancel the execution of this AsyncTask
, for example, the user of a very fast scroll:
Add a AsyncTask
within your ViewHolder:
...
private class ViewHolder{
public ImageView image;
public AsyncTask<Void, Void, Bitmap> asyncTask;
...
}
Within the getView()
method of your adapter:
...
//Previnindo o recycle de view
if (holder.asyncTask != null) {
holder.asyncTask.cancel(true);
holder.asyncTask = null;
}
//Previnido que a imagem "pisque" caso de um scroll muito rápido;
holder.image.setImageResource(R.drawable.someDrawable);
final ImageView image = holder.image;
holder.asyncTask = new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
//Aqui você faz as implementações a seguir
}
@Override
protected void onPostExecute(Bitmap bitmap) {
image.setImageBitmap(bitmap);
}
};
holder.asyncTask.execute();
2) Within your AsyncTask, you can use a property called inSampleSize
, which does what decodes your image into a smaller resolution, as if it were a "sample" of your image. For example, an image of 2048x1536 using inSampleSize as 4 produces an image with approximately 512x384. This loaded image uses only 0.75MB of memory instead of 12MB of the original image size. You can use this property within BitmapFactory.Options
:
//Dentro de sua AsyncTask criada
@Override
protected Bitmap doInBackground(Void... params) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
/*Reduzindo a qualidade da imagem para preservar memoria.
* Aqui você pode testar a redução que melhor atende sua necessidade
*/
options.inSampleSize = 2;
return BitmapFactory.decodeStream(new FileInputStream(imagePath), null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
Sources:
Loading Large Bitmaps Efficiently
Processing Bitmaps Off the UI Thread