滚动时列表视图崩溃“应用程序可能在其主线程上执行了太多工作。”

时间:2013-07-26 23:39:54

标签: android performance listview android-listview

我正在尝试使用以下代码创建一个平滑滚动的列表视图:

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

// tt是包含100个对象的x(Object)数组。

x[] tt= response.getX();

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

//适配器列表视图

 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;
}

当我滚动此列表时,此处崩溃的应用程序就是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

如何处理这些错误?我做错了什么?

2 个答案:

答案 0 :(得分:2)

首先,

我认为使用

时问题出在getView中
LayoutInflater inflator = ((Activity) myContext).getLayoutInflater();

无需将其强制转换为(Activity)并使用该layoutInflater。

当我看到您在适配器的custructor中传递上下文时,您可以使用

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

另外,如果你想正确实现ViewHolder patern,你应该这样做:

       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();
        }

<强>更新

通常,为了使列表视图更快,您应该尝试使getView()简单快速,并且我的意思是您应该使用它来将数据打印到具有预先填充值的用户。

为了做到这一点,你应该正确地实现视图模式和 从不在getView中访问数据库或从互联网获取值。

之后我可能在您的代码中找到问题的唯一可能原因是方法

xdata.getMsisdn() and etrData.getPrice()

除了获取访问互联网或数据库等值之外,还在后台做些什么?

答案 1 :(得分:0)

我认为问题可能是模拟器中的错误。您使用的是模拟器还是实际设备?我使用Manos描述的模式看到了这种行为 - 很棒的提示! - 使用20项硬编码字符串数组。

如果我使用2.3.3仿真器,也没有问题。如果我使用2.2.3或4.1.1实际设备,也没有问题。