【问题标题】:Large set of data in listview crashing the android app列表视图中的大量数据使 android 应用程序崩溃
【发布时间】:2013-02-13 06:25:46
【问题描述】:

您好,我需要在 Android 应用程序的 Listview 中管理大量数据。列表项可能在 250 左右或更多。现在我的问题是,当我滚动列表视图时,由于更多项目,它会使应用程序崩溃。但是当项目少于 100 时,列表视图会正常工作。

请帮我解决这个问题。

这是我的错误日志。

02-13 06:43:07.320: ERROR/AndroidRuntime(1776): Caused by: java.lang.OutOfMemoryError
android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:577)
android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:445)
android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:738)
android.content.res.Resources.loadDrawable(Resources.java:1869)
android.content.res.Resources.getDrawable(Resources.java:659)
android.widget.ScrollView.setOverScrollMode(ScrollView.java:1487)
android.view.ViewGroup.<init>(ViewGroup.java:365)
android.widget.FrameLayout.<init>(FrameLayout.java:94)
android.widget.ScrollView.<init>(ScrollView.java:155)
android.widget.ScrollView.<init>(ScrollView.java:151)

而我的getView()

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

    final int pos = position;
    views = null;
    LayoutInflater layoutInflator = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    views = (RelativeLayout) layoutInflator.inflate(
            R.layout.guest_list_item, null);

    final CheckBox chk = (CheckBox) views.getChildAt(0);
    // Log.d("", "CheckBox Pos "+position);
    chk.setId(position);

    TextView txtView = (TextView) views.getChildAt(1);

    TextView txtView2 = (TextView) views.getChildAt(2);
    TextView txtView3 = (TextView) views.getChildAt(3);

    final TextView txtView4 = (TextView) views.getChildAt(4);
    TextView txtView5 = (TextView) views.getChildAt(6);
    txtView5.setId(position);

    // Log.d("", "Button Pos "+position);
    txtView4.setId(position);

    txtView4.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(context, InfoScreen.class);
            intent.putExtra("IDVALUE", arTempId.get(txtView4.getId()));
            intent.putExtra("IDVALUE", arrayListId.get(position));

            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            context.startActivity(intent);
            // System.out.println(v + "##########" + " " + v.getId());
            // System.out.println(v + "##########" + " " +
            // arTempId.get(txtView4.getId()));
            // System.out.println(v + "##########" + " " +
            // chickinlist.get(txtView4.getId()));
        }
    });
    Log.e("", "****************************************************** ");
    // Log.v("", "Adapter arr pos " + pos);
    // Log.v("", "Adapter arr position " + position);
    Log.v("", "Adapter arr size " + arrayListFirstName.size());
    Log.v("", "Passsing arr size " + chickinlist.size());

    for (int dd = 0; dd < arrayListFirstName.size(); dd++) {
        if (position == dd) {
            // Log.d("", "Passsing arr size " + chickinlist.size());
            Boolean result = chickinlist.get(position);
            // Log.d("", "After " + result);
            if (result == true) {
                chk.setChecked(true);
                arrCheckedItems.add(position);
                views.setBackgroundResource(R.drawable.list_item_checked);

            } else {
                chk.setChecked(false);
                arrUnCheckedItems.add(position);
                views.setBackgroundResource(R.drawable.list_item_unchecked);

            }

            txtView.setText(arrayListFirstName.get(position));
            txtView2.setText(arrayListLastName.get(position));
            txtView3.setText("(" + arrayListGuests.get(position) + ")");
            if (arrayCustomOne.get(position).equalsIgnoreCase("0")
                    || arrayCustomOne.get(position).equalsIgnoreCase(null)
                    || arrayCustomOne.get(position).equalsIgnoreCase(
                            "(null)")) {
                txtView5.setText("");
            } else {
                txtView5.setText(arrayCustomOne.get(position));
            }

        }

    }

    chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            mySqliteAdapter.openToWrite();

            sId = arrayListId.get(chk.getId());
            // Log.d("Adapter",
            // "Checked Temp Id "+arTempId.get(chk.getId()));
            Log.d("",
                    "Position " + chk.getId() + "tempid "
                            + arTempId.get(chk.getId()));

            if (isChecked) {

                chk.setChecked(true);
                arrCheckedItems.add(position);
                strAlertValue = "1";
                sCheckIn = "1";
                strExe = "update ticket_details set checkin_status=1 where tempid="
                        + arTempId.get(chk.getId());
                mySqliteAdapter.executeCheckQurey(strExe);
                if (Util.getInstance(context).isTabletDevice()) {
                    buttonView
                            .setBackgroundResource(R.drawable.tablet_list_item_check);
                } else {
                    buttonView
                            .setBackgroundResource(R.drawable.list_item_checked);
                }

                new CheckInUpdate().execute();
                AlertDialog.Builder builder = new AlertDialog.Builder(
                        context);
                builder.create();
                builder.setMessage(arrayListFirstName.get(chk.getId())
                        + " " + arrayListLastName.get(chk.getId())
                        + " has been checked in.");
                builder.setPositiveButton("Ok",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                    int which) {
                                // myGuestList = new GuestListScreen();

                                //
                                // // myGuestList.ListUpdate();

                                //Intent intentNavGuestList = new Intent(
                                //context, GuestListScreen.class);
                                //intentNavGuestList
                                //                                          .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                                //context.startActivity(intentNavGuestList);

                                dialog.dismiss();

                            }

                        }).show();

                // Log.d("", "ID = " + buttonView.getId());

            }
            if (!isChecked) {

                sCheckIn = "0";
                strAlertValue = "0";

                // views.setBackgroundResource(R.drawable.list_item_unchecked);
                strExe = "update ticket_details set checkin_status=0 where tempid="
                        + arTempId.get(chk.getId());

                mySqliteAdapter.executeCheckQurey(strExe);

                if (Util.getInstance(context).isTabletDevice()) {
                    buttonView
                            .setBackgroundResource(R.drawable.tablet_list_item_uncheck);
                } else {
                    buttonView
                            .setBackgroundResource(R.drawable.list_item_unchecked);
                }
                new CheckInUpdate().execute();


                Intent intentNavGuestList = new Intent(context,
                        GuestListScreen.class);
                intentNavGuestList
                        .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                context.startActivity(intentNavGuestList);

                // Toast.makeText(context, "check release",
                // Toast.LENGTH_SHORT)
                // .show();
                // new CheckInUpdate().execute();

            }

        }
    });

    return views;

}

【问题讨论】:

  • 请发布您的适配器的getView方法。
  • 在列表视图中拥有超过 250 个项目不会导致应用程序崩溃,发布您的 logcat 和您的代码也许我们可以帮助您。
  • 向我们展示 getView 方法代码和您的数据数组结构。你做错了什么)
  • 如果您的 listView 包含图像和视频,那么我可以说我们在同一页面上。我是如何解决这个问题的:我在布局中使用了滚动功能并在其中膨胀了视图。它上升到 250。在接近 300 时它崩溃了。它用作列表视图。也可以在其中加载图像和视频。

标签: android listview


【解决方案1】:

Holder Pattern 是一个正确的答案。如果你为列表视图实现“分页”模式会更好。当列表视图滚动到结束时显示下一个项目。还要避免在适配器中执行长时间运行的任务。将数据和适配器分开。请参阅使用 notifyDataSetChanged() 方法。

【讨论】:

    【解决方案2】:

    猜测 - 您没有重复使用视图。
    尝试使用 View Holder -这里有一些链接 -
    http://developer.android.com/training/improving-layouts/smooth-scrolling.html http://vsvydenko.blogspot.in/2011/06/android-use-viewholder.html http://www.jmanzano.es/blog/?p=166

    建议 - 让你的适配器实现 OnClickListenerOnCheckedChangeListener

    public class YourAdapter  implements OnCheckedChangeListener, OnClickListener....
    

    然后通过 -

    分别处理这些事件
    @Override
    public void onClick(View v) {
        // Do your stuff here
    
    }
    

    OnCheckedChangeListener 一样。

    这样代码将具有更好的可读性和易于调试。

    【讨论】:

    • 感谢现在滚动工作顺利,但 OutOfMemory 错误仍然发生。
    • @Dhamodharan:检查编辑。
    • 我知道它很旧,但是当视图被重用时,我不会在 ListView 中使用 OnCheckedChangeListener ...每次滚动时,视图都会被重用,并且它们的检查状态将更改,它将调用该侦听器。您最好使用 OnClick 并将单击状态保存在数据对象中。
    猜你喜欢
    • 2016-07-19
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多