You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从数据库取数据填充自定义ListView时遇IndexOutOfBoundsException崩溃

Hey there! Let's work through this java.lang.IndexOutOfBoundsException crash you're hitting with your SQLite-powered ListView. The error message makes it clear: your adapter is trying to access index 0, but your data list has 0 items—so there's nothing to fetch at that position. Let's break down how to fix this step by step.

1. Root Cause Breakdown

This error happens for one of two core reasons:

  • Your SQLite query is returning an empty list (either the database has no data, or your query is broken)
  • You're attaching the adapter to the ListView before your data is loaded, or the adapter isn't properly handling an empty data set

2. Step-by-Step Fixes

First: Validate Your SQLite Query (Check DbHelper)

Let's start with your DbHelper.java—this is where your data comes from, so we need to make sure it's pulling data correctly. Here's a corrected example of a data-fetching method, with safeguards:

public class DbHelper extends SQLiteOpenHelper {
    // ... constructor and onCreate/onUpgrade methods ...

    public List<YourDataModel> getAllItems() {
        List<YourDataModel> itemList = new ArrayList<>();
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM your_table_name", null);

        // Only iterate if the cursor has data
        if (cursor.moveToFirst()) {
            do {
                // Use getColumnIndexOrThrow to catch typos in column names
                YourDataModel item = new YourDataModel();
                item.setId(cursor.getInt(cursor.getColumnIndexOrThrow("id")));
                item.setTitle(cursor.getString(cursor.getColumnIndexOrThrow("title")));
                // Add other fields here
                itemList.add(item);
            } while (cursor.moveToNext());
        }

        // Always close cursors and databases to avoid leaks
        cursor.close();
        db.close();
        return itemList;
    }
}

Key checks for your DbHelper:

  • Double-check table/column names—typos here are the #1 cause of empty results
  • Use getColumnIndexOrThrow() instead of getColumnIndex(): it'll throw an explicit error if a column doesn't exist, making debugging easier
  • Confirm your database actually has data (use tools like SQLiteStudio to inspect the .db file)

Second: Fix Your CustomAdapter's Data Handling

The crash happens on line 68 of CustomAdapter.java—that's almost certainly a line where you're calling mDataList.get(position) when mDataList is empty. Let's harden the adapter to handle empty sets:

public class CustomAdapter extends BaseAdapter {
    private List<YourDataModel> mDataList;
    private Context mContext;

    // Initialize with a non-null list to avoid null pointers
    public CustomAdapter(Context context, List<YourDataModel> dataList) {
        mContext = context;
        mDataList = dataList != null ? dataList : new ArrayList<>();
    }

    @Override
    public int getCount() {
        // Return the actual size of the list—never a fixed number!
        return mDataList.size();
    }

    @Override
    public Object getItem(int position) {
        return mDataList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Add a safety check to avoid out-of-bounds access
        if (position < 0 || position >= mDataList.size()) {
            return convertView != null ? convertView : new View(mContext);
        }

        // Rest of your getView logic—inflating layout, binding data, etc.
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.your_list_item, parent, false);
            holder = new ViewHolder();
            holder.titleTv = convertView.findViewById(R.id.title_tv);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        YourDataModel item = mDataList.get(position);
        holder.titleTv.setText(item.getTitle());
        // Bind other views here

        return convertView;
    }

    // ViewHolder pattern to optimize performance
    private static class ViewHolder {
        TextView titleTv;
        // Add other views here
    }
}

Third: Fix Your Data Loading Flow in the Activity/Fragment

Never attach an empty adapter to the ListView before loading data. Wait until you have the data from SQLite, then initialize and set the adapter:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ListView listView = findViewById(R.id.your_list_view);
    DbHelper dbHelper = new DbHelper(this);

    // Fetch data FIRST, then set the adapter
    List<YourDataModel> dataList = dbHelper.getAllItems();

    // Handle empty list case gracefully (no crash!)
    if (dataList.isEmpty()) {
        // Show a "no data" message instead of a blank list
        TextView emptyStateTv = findViewById(R.id.empty_state_tv);
        emptyStateTv.setVisibility(View.VISIBLE);
        listView.setVisibility(View.GONE);
    } else {
        CustomAdapter adapter = new CustomAdapter(this, dataList);
        listView.setAdapter(adapter);
    }
}

If you're loading data asynchronously (e.g., with Kotlin Coroutines or AsyncTask), make sure you update the adapter on the main thread after data is fetched.

3. Quick Debugging Tips

  • Add log statements in your DbHelper to confirm data count: Log.d("DbHelper", "Fetched items: " + itemList.size());
  • Log the data count in your adapter's constructor: Log.d("CustomAdapter", "Received items: " + mDataList.size());
  • Inspect line 68 of your adapter—if it's mDataList.get(position), the fix above will prevent the crash when the list is empty

内容的提问来源于stack exchange,提问作者Yashna C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:00:47