Android Java SQLite条件查询后ListView加载崩溃问题求助
Android SQLite条件查询崩溃:Spinner选分组后加载ListView无响应最终崩溃
问题场景
已实现SQLite分组数据正常加载至Spinner,但选择分组后进度圈持续运行,最终APP崩溃,无明显报错信息。
排查与修复方案
1. 解决主线程阻塞问题
数据库查询属于耗时操作,若直接在主线程执行会引发ANR(应用无响应)进而崩溃。必须将查询逻辑放到子线程执行:
// 在SelectContactsActivity的Spinner选择事件中 spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String selectedGroup = parent.getItemAtPosition(position).toString(); progressDialog.show(); // 用AsyncTask执行异步查询 new AsyncTask<String, Void, Cursor>() { @Override protected Cursor doInBackground(String... params) { // 子线程中执行数据库查询 return contactsDbAdapter.getContactsByGroup(params[0]); } @Override protected void onPostExecute(Cursor cursor) { // 主线程更新ListView并关闭进度圈 customContactsAdapter.changeCursor(cursor); progressDialog.dismiss(); } }.execute(selectedGroup); } @Override public void onNothingSelected(AdapterView<?> parent) {} });
2. 修复Cursor内存泄漏
未正确关闭旧Cursor会导致内存耗尽,需在自定义Adapter中处理:
public class CustomContactsAdapter extends CursorAdapter { // ... 其他实现代码 @Override public void changeCursor(Cursor newCursor) { Cursor oldCursor = getCursor(); super.changeCursor(newCursor); // 关闭旧Cursor释放资源 if (oldCursor != null && !oldCursor.isClosed()) { oldCursor.close(); } } // Activity销毁时关闭数据库连接 @Override protected void onDestroy() { super.onDestroy(); contactsDbAdapter.close(); if (customContactsAdapter.getCursor() != null) { customContactsAdapter.getCursor().close(); } } }
3. 优化SQL查询性能
若分组下数据量过大或查询无索引,会导致查询超时崩溃:
- 给分组字段添加索引:
// 在ContactsDetailsDbAdapter的表创建语句中添加索引 private static final String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_GROUP + " TEXT," + // 其他字段 + "CREATE INDEX idx_contact_group ON " + TABLE_CONTACTS + "(" + KEY_GROUP + ");"; - 避免
SELECT *,只查询ListView需要的字段,减少数据传输量。
4. 强制捕获异常获取报错信息
即使表面无报错,也能通过try-catch捕获异常日志:
// 在AsyncTask的doInBackground中添加异常捕获 @Override protected Cursor doInBackground(String... params) { try { return contactsDbAdapter.getContactsByGroup(params[0]); } catch (Exception e) { e.printStackTrace(); // 查看Logcat的Error级别日志,定位具体崩溃原因 return null; } }
内容的提问来源于stack exchange,提问作者Maria
相关产品推荐
相关产品推荐

