Mohammed Saleem
Mohammed Saleem

Reputation: 578

List view crashes when scrolling "The application may be doing too much work on its main thread."

I am trying to create a list view that smoothly scrolls with the following code:

 <ListView
        android:id="@+id/list2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:listSelector="@android:color/transparent" />

// tt is and array of x (Object)that have 100 objects.

x[] tt= response.getX();

ItemsAdapter myListAdapter = new ItemsAdapter(getActivity(),R.layout.mylist, tt);
// setListAdapter(myListAdapter);
list2.setAdapter(myListAdapter);

// the adapter listview

 public class ItemsAdapter extends BaseAdapter {
    Context myContext;
    private int customLayoutId = -1;
    private X[] items;

    public ItemsAdapter(Context context, int resource, X[] x) {

        customLayoutId = resource;
        myContext = context;
        this.items = x;

    }

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

        // View row = convertView;

        try {
            LayoutInflater inflator = ((Activity) myContext)
                    .getLayoutInflater();

            xdata= items[position];

            if (convertView == null) {
                // row = inflater.inflate(customLayoutId, null);
                convertView = inflator.inflate(customLayoutId, null);
                DataViewHolder viewHolder1 = null;

                viewHolder1 = new DataViewHolder();

                viewHolder1.numberTV = (TextView) convertView
                        .findViewById(R.id.numberTV);
                viewHolder1.costTV = (TextView) convertView
                        .findViewById(R.id.costTV);
                viewHolder1.reserveButton = (Button) convertView
                        .findViewById(R.id.reserveButton);
                viewHolder1.reserveButton
                        .setBackgroundResource(R.drawable.reserve_button);

                viewHolder1.position = position;

                convertView.setTag(viewHolder1);
            }


            DataViewHolder viewHolder1 = (DataViewHolder) convertView
                    .getTag();


            viewHolder1.numberTV.setText(xdata.getMsisdn());

            viewHolder1.costTV.setText(etrData.getPrice());

            viewHolder1.reserveButton
                    .setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {



                    });

        } catch (Exception e) {
            e.printStackTrace();
        }

        return convertView;
    }

 }

  @Override
    public int getCount() {

        return this.items.length;
    }

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

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

static class DataViewHolder {
    public TextView numberTV;
    public TextView costTV;
    public Button reserveButton;
    public int position;
}

When I scroll this list, the app crashes here is what is in Logcat:

07-27 02:50:26.756: I/Choreographer(24450): Skipped 46 frames!  The application may be       doing too much work on its main thread.
07-27 02:50:27.497: I/Choreographer(24450): Skipped 41 frames!  The application may be doing too much work on its main thread.
07-27 02:50:28.698: I/Choreographer(24450): Skipped 32 frames!  The application may be doing too much work on its main thread.

07-27 02:50:34.724: D/dalvikvm(24450): GC_CONCURRENT freed 1120K, 12% free 13993K/15815K, paused 6ms+6ms, total 35ms

07-27 02:50:35.655: I/Choreographer(24450): Skipped 41 frames!  The application may be doing too much work on its main thread.
07-27 02:50:45.685: I/Choreographer(24450): Skipped 58 frames!  The application may be doing too much work on its main thread.
07-27 02:50:46.936: I/Choreographer(24450): Skipped 69 frames!  The application may be doing too much work on its main thread.
07-27 02:50:57.677: I/Choreographer(24450): Skipped 31 frames!  The application may be doing too much work on its main thread.
07-27 02:50:59.639: I/Choreographer(24450): Skipped 53 frames!  The application may be doing too much work on its main thread.
07-27 02:51:03.953: D/TextLayoutCache(24450): Cache value 0x54a260f0 deleted, size = 280
07-27 02:51:03.963: D/TextLayoutCache(24450): Cache value 0x41002fd0 deleted, size = 400
07-27 02:51:03.963: D/TextLayoutCache(24450): Cache value 0x40f05908 deleted, size = 360
07-27 02:51:04.113: D/TextLayoutCache(24450): Cache value 0x413aa480 deleted, size = 384
07-27 02:51:04.123: D/TextLayoutCache(24450): Cache value 0x413a6200 deleted, size = 408

How should these errors be dealt with? What am I doing wrong?

Upvotes: 2

Views: 3667

Answers (2)

Steve Gelman
Steve Gelman

Reputation: 932

I think the problem might be a bug in the emulator. Are you using an emulator or an actual device? I see this behavior using the pattern Manos describes above -- nice tip! -- with a 20 item array of hard-coded strings.

If I use my 2.3.3 emulator, there is no problem either. If I use either a 2.2.3 or 4.1.1 actual device, there is no problem, either.

Upvotes: 0

Manolis Proimakis
Manolis Proimakis

Reputation: 1785

First of all,

I think the problem is in the getView when you use

LayoutInflater inflator = ((Activity) myContext).getLayoutInflater();

there is no need to cast it to (Activity) and use that layoutInflater.

and as i see that you pass context in the custructor of your adapter you can just use

LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Also if you want to implement the ViewHolder patern correctly you should do it like this:

       DataViewHolder viewHolder1 = null;
       if (convertView == null) {
            // row = inflater.inflate(customLayoutId, null);
            convertView = inflator.inflate(customLayoutId, null);
            viewHolder1 = new DataViewHolder();
            viewHolder1.numberTV = (TextView) convertView.findViewById(R.id.numberTV);
            viewHolder1.costTV = (TextView) convertView.findViewById(R.id.costTV);
            viewHolder1.reserveButton = (Button)convertView.findViewById(R.id.reserveButton);      
            viewHolder1.reserveButton.setBackgroundResource(R.drawable.reserve_button);
            viewHolder1.position = position;
            convertView.setTag(viewHolder1);
        }
        else{
            viewHolder1 = (DataViewHolder) convertView.getTag();
        }

Update:

Generally, in order to make a listview faster , you should try to make getView() simple and fast, and with that i mean that you should pretty much use it to print your data to the user with prepopulated values.

In order to do that you should correctly implement the viewholder pattern and never access database or get Values from internet in the getView.

After that the only possible reason for your problem i may find in your code is if the methods

xdata.getMsisdn() and etrData.getPrice()

do something in the background other than getting values like accessing internet or a database?

Upvotes: 2

Related Questions