0

I have implemented GridView in my app, using the BaseAdapter. After following the recommended practices for any ListView (use of ViewHolder, recycling the View and Universal Image Loader to load images asynchronously), I'm still not satisfied with the performance; the scrolling of the Grid is still not very smooth and the activity crashes if I scroll continuously up and down for about 5-6 seconds (without throwing any exception).

During the scrolling action I frequently get the following in my logcat -

I/Choreographer﹕ Skipped 32 frames! The application may be doing too much work on its main thread. where 32 could also shoot up-to 54 frames.

Here is my code for the Cursor Adapter -

public class ContestantListCustomGridAdapter extends BaseAdapter {

    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private Cursor allContestantShortInfo;

    GlobalMethods gm = new GlobalMethods();

    public ContestantListCustomGridAdapter(Context c) {

        mContext = c;

        String[] columns = new String[] {Database.ColumnOne,
                Database.ColumnTwo,
                Database.ColumnThree,
                Database.ColumnFour,
                Database.ColumnFive,
                Database.ColumnSix,
                };

        //Get data from the DB
        Database db = new Database(mContext);
        db.open();
        this.allContestantShortInfo = db.getValuesFromTable(Database.CONTESTANT_SHORT_INFO_TABLE,
                columns, Database.CONTESTANT_SHORT_INFO_EVENT_ID + "=" + GlobalConstants.eventId,
                null, null, null, null);
        db.close();
        allContestantShortInfo.moveToFirst();

        mLayoutInflater = LayoutInflater.from(c);
    }

    @Override
    public int getCount() {
        return allContestantShortInfo.getCount();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    static class ViewHolder {
        TextView participantName;
        TextView participantCountry;
        TextView participantLikes;
        RelativeLayout participantEliminated;
        ImageView participantImage;
    }

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

        final ViewHolder holder;

        if (convertView == null) {

            convertView = mLayoutInflater.inflate(R.layout.grid_view_card_layout, parent, false);
            holder = new ViewHolder();
            holder.participantEliminated = (RelativeLayout) convertView.findViewById(R.id.Card_isEliminated);
            holder.participantName = (TextView) convertView.findViewById(R.id.grid_model_name);
            holder.participantCountry = (TextView) convertView.findViewById(R.id.grid_country_name);
            holder.participantLikes = (TextView) convertView.findViewById(R.id.participant_total_likes_number);
            holder.participantImage = (ImageView) convertView.findViewById(R.id.grid_model_image);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        applyTypeFace(convertView);

        //Set the values into placeholders
        allContestantShortInfo.moveToPosition(position);
        holder.participantName.setText(allContestantShortInfo
                .getString(GlobalConstants.CONTESTANT_SHORT_INFO_NAME_INDEX));
        holder.participantCountry.setText(allContestantShortInfo
                .getString(GlobalConstants.CONTESTANT_SHORT_INFO_COUNTRY_NAME_INDEX));
        holder.participantLikes.setText(allContestantShortInfo
                .getString(GlobalConstants.CONTESTANT_SHORT_INFO_LIKES_INDEX));

        if(allContestantShortInfo.getString(GlobalConstants.CONTESTANT_SHORT_INFO_ELIMINATION_STATUS_INDEX)
                .equalsIgnoreCase("true")) {
            holder.participantEliminated.setVisibility(View.VISIBLE);
            holder.participantImage.setColorFilter(Color.parseColor("#90000000"));
        } else {
            holder.participantEliminated.setVisibility(View.GONE);
            holder.participantImage.setColorFilter(0);
        }

        ImageLoader.getInstance()
                .displayImage(allContestantShortInfo
                                .getString(GlobalConstants.CONTESTANT_SHORT_INFO_WEB_APP_PATH_INDEX) +
                              allContestantShortInfo
                                .getString(GlobalConstants.CONTESTANT_SHORT_INFO_THUMBNAIL_IMAGE_URL_INDEX),
                        holder.participantImage);

        return convertView;
    }
}

What could possibly be improved so that I can get my GridView to be as smooth as any other ListView and it does not crash too.

krtkush
  • 1,378
  • 4
  • 23
  • 46

2 Answers2

0

For every getView you are working with database and using cursor, I think the lag caused by asking the cursor to move or read.

first read your content of your database at the constructor of adapter and create ArrayList of your parameter and then use from ArrayList to populate your data.

if your data is very large you can read chunk by chunk for example read 0-100 items and when user scrolls and reachs for item 90 read for example 100-110 and delete 0-10 to prevent to get OOM.

mmlooloo
  • 18,937
  • 5
  • 45
  • 64
  • This did not really help. The activity still crashes after skipping frames to 92. I have total of 40 images in my gridview; I don't think I should have to read by chunk. – krtkush Oct 08 '14 at 19:58
  • http://stackoverflow.com/questions/14678593/the-application-may-be-doing-too-much-work-on-its-main-thread – mmlooloo Oct 09 '14 at 02:45
  • I moved the read from DB part to the grid activity; the activity which calls the adapter. It first loads the data from the DB and then only calls the adapter, passing the loaded cursor in the constructor of the adapter. – krtkush Oct 09 '14 at 06:24
  • you can also read data in activity store it in arraylist and close the cursor, after that just pass the arraylist to the adapter. another option is using simplecursoradapter. – mmlooloo Oct 09 '14 at 06:30
  • I found the problem; it was my method which was setting the typeface that was the cause. – krtkush Oct 10 '14 at 06:27
0

The lag was being caused by my method applyTypeFace(convertView). Removing it solved the problem.

krtkush
  • 1,378
  • 4
  • 23
  • 46