Android Studio中AutocompleteTextView取值及点击按钮崩溃问题排查
问题分析与修复
核心问题1:错误的视图判断逻辑
你的代码里if (view == View)完全错误——View是类,view是当前点击的视图对象,两者永远不可能相等。这行代码会导致查询逻辑根本不会执行,显然是笔误,应该改成判断点击的是目标按钮,比如:
// 先在onCreate中初始化查看按钮 Button btnView = findViewById(R.id.btn_view); // 点击回调里判断视图 if (view == btnView) { // 后续查询逻辑 }
核心问题2:Dept赋值崩溃的直接原因
崩溃出现在Dept.setText(c.getString(3)),大概率是以下几种情况:
情况1:数据库列索引错误
Cursor的索引从0开始,你需要确认student表的列顺序:如果表结构是rollno(0), name(1), marks(2), dept(3),索引3才对应dept;如果dept是第3列(索引2),或者表中根本没有dept列,就会抛出CursorIndexOutOfBoundsException。
修复方案:不要硬编码索引,改用列名获取,避免列顺序变化导致错误:
int deptColumnIndex = c.getColumnIndex("dept"); if (deptColumnIndex != -1 && !c.isNull(deptColumnIndex)) { Dept.setText(c.getString(deptColumnIndex)); } else { Dept.setText(""); // 或设置默认提示文本 }
情况2:AutocompleteTextView未初始化
检查Dept是否在onCreate中通过findViewById正确获取实例:
// 假设你的AutocompleteTextView的id是autocomplete_dept AutocompleteTextView Dept = findViewById(R.id.autocomplete_dept);
如果没有初始化,调用setText()会抛出NullPointerException。
情况3:数据库字段为空
如果student表中对应rollno的dept字段为空,直接调用c.getString(3)会抛出异常,需要先判断是否为空:
if (!c.isNull(3)) { Dept.setText(c.getString(3)); } else { Dept.setText("无部门信息"); }
修复后的完整代码示例
// 初始化控件 Button btnView = findViewById(R.id.btn_view); AutocompleteTextView Dept = findViewById(R.id.autocomplete_dept); EditText Rollno = findViewById(R.id.rollno); EditText Name = findViewById(R.id.name); EditText Marks = findViewById(R.id.marks); // 点击回调逻辑 if (view == btnView) { String rollNoStr = Rollno.getText().toString().trim(); // 检查学号是否为空 if (rollNoStr.length() == 0) { showMessage("Error", "Please enter Rollno"); return; } // 用参数化查询避免SQL注入 Cursor c = db.rawQuery("SELECT * FROM student WHERE rollno=?", new String[]{rollNoStr}); if (c.moveToFirst()) { Name.setText(c.getString(c.getColumnIndex("name"))); Marks.setText(c.getString(c.getColumnIndex("marks"))); int deptIndex = c.getColumnIndex("dept"); if (deptIndex != -1 && !c.isNull(deptIndex)) { Dept.setText(c.getString(deptIndex)); } else { Dept.setText(""); } } else { showMessage("Error", "Invalid Rollno"); clearText(); } // 关闭Cursor避免内存泄漏 c.close(); }
额外提醒:SQL注入风险
原代码用字符串拼接SQL语句,存在SQL注入风险,建议改用参数化查询(如上面代码中的rawQuery("SELECT * FROM student WHERE rollno=?", new String[]{rollNoStr})),避免恶意输入破坏数据库。
内容的提问来源于stack exchange,提问作者user17369875
相关产品推荐
相关产品推荐

