ListView locking a lot on scroll

2

My ListView is crashing a lot on the scroll, I already tried to implement the ViewHolder to the Adapter but it did not solve, could you help me?

Adapter:

public class Adapter extends SimpleAdapter {
    private Context context;
    public LayoutInflater inflater = null;

    public Adapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
    {
        super(context, data, resource, from, to);

        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        ViewHolder viewHolder;

        HashMap<String, Object> data = (HashMap<String, Object>) super.getItem(position);

        if(view == null){
            view = inflater.inflate(R.layout.clientes, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
            viewHolder.title = (TextView)view.findViewById(R.id.title);
            viewHolder.content = (TextView)view.findViewById(R.id.content);

            view.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder)view.getTag();
        }

        try {
            viewHolder.thumbnail.setImageBitmap( new DownloadTask().execute(data.get("thumbnail").toString()).get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        viewHolder.title.setText(data.get("title").toString());
        viewHolder.content.setText(data.get("content").toString());

        return view;
    }

    static class ViewHolder{
        ImageView thumbnail;
        TextView title;
        TextView content;
    }
}

DownloadTask:

public class DownloadTask extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected void onPreExecute() {}

    @Override
    protected Bitmap doInBackground(String... params) {
        Bitmap image = null;

        try {
            image = BitmapFactory.decodeStream( new URL(params[0]).openConnection().getInputStream());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return image;
    }
}
    
asked by anonymous 22.07.2015 / 04:28

2 answers

2

The problem is that the get () method of < in> AsyncTask only returns when the doInBackground() method finishes. You are using AsyncTask synchronously.

Change the DownloadTask class to receive the viewHolder.thumbnail and make the setImageBitmap() in the onPostExecute() method.

public class DownloadTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> imageView;

    public DownloadTask(ImageView thumbnail) {
        imageView = new WeakReference<ImageView>(thumbnail);
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        Bitmap image = null;

        try {
            image = BitmapFactory.decodeStream( new URL(params[0]).openConnection().getInputStream());
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return image;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {

        ImageView thumbnail = imageView.get();
        if (thumbnail != null) {
            if (bitmap != null) {
                thumbnail.setImageBitmap(bitmap);
            }
        }
    }
}

Adapter change the line

viewHolder.thumbnail.setImageBitmap(new DownloadTask()
                       .execute(data.get("thumbnail").toString()).get());

for

new DownloadTask(viewHolder.thumbnail).execute(data.get("thumbnail").toString());
    
22.07.2015 / 14:35
2

I think your problem might be this one:

viewHolder.thumbnail.setImageBitmap( new DownloadTask().execute(data.get("thumbnail").toString()).get());

I'm guessing because I'm not seeing your DownloadTask implementation. In Android all operations are performed on the Main Thread, which is the UI thread. If you are doing any Bitmap operation on this thread, your ViewHolder will be very slow and may even crash the application.

EDIT: We've already seen that the problem was DownloadTask, but now you're having trouble managing your Bitmaps cache . To not get off topic I suggest you open a new thread and close this thread. It is suggested to analyze some solution already tested in some code, like the Universal Loader .

    
22.07.2015 / 04:45