java - 将数据库记录加载到 Spinner 时出错
问题描述
我正在为我的 A2 级计算机科学课程作业开发应用程序,并且在尝试将数据库表中的数据加载到微调器时遇到错误。我希望在微调器中包含所有领导者的身份证、名字和姓氏,但是我遇到了一个错误。这是我为数据库处理程序编写的代码:
private static final String CREATE_TABLE_EVENTS=("CREATE TABLE " + TABLE_EVENTS + "("
+ COLUMN_SEID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_SNAME + " TEXT,"
+ COLUMN_STYPE + " TEXT,"+ COLUMN_SDATE + " TEXT," + COLUMN_EDATE + " TEXT,"
+ COLUMN_STIME + " TEXT," + COLUMN_ETIME + " TEXT," + COLUMN_VENUE + " TEXT,"
+ COLUMN_DESC + " TEXT," + COLUMN_SCID + " INTEGER," + COLUMN_EMAIL + " TEXT,"
+ COLUMN_ACOST + " REAL," + COLUMN_INV + " INTEGER," + COLUMN_PCOST + " REAL,"
+ COLUMN_FOOD + " TEXT," + COLUMN_TINC + " TEXT," + COLUMN_DIST + " INTEGER,"
+ COLUMN_TCOST + " REAL )"); //The columns had been defined earlier
...
//Search for leaders for spinner for purpose of creating an event
public String[][] eventLeadersSearch() {
int CursorPosition;
String[][] leadersList =new String[3][];
String ScoutSection = "Leaders";
String query = "SELECT " + COLUMN_SCID + ", " + COLUMN_FNAME + ", " + COLUMN_LNAME +" FROM " + TABLE_SCOUTS + " WHERE " + COLUMN_SECTION + " LIKE '" + ScoutSection + "'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
int rowsFound=cursor.getCount();
int x=0;
if (rowsFound>0) {
cursor.moveToFirst();
do {
CursorPosition = cursor.getPosition();
leadersList[0][x] = Integer.toString((cursor.getInt(0)));//DEFINITELY SOMETHING WRONG HERE
leadersList[1][x] = cursor.getString(1);
leadersList[2][x] = cursor.getString(2);
x = x + 1;
cursor.moveToNext();
}
while (!cursor.isAfterLast());
}
else {
Log.e("Database Error", "No Leaders Found");
}
cursor.close();
db.close();
return leadersList;
}
我使用二维数组的原因是稍后,我希望能够返回并检索有关该领导者的更多详细信息 - 但是这将在不同的屏幕上,因此在不同的类中。因此,我也希望能够单独保留所有细节。
这是我编写的将所有值放入微调器的代码:
private void loadSpinnerData(){
databaseHandler db=new databaseHandler(getApplicationContext());
String[][] Leaders=db.eventLeadersSearch(); //Error here
List<String> LeadersInOne=new ArrayList<>();
for (int i=0; i<Leaders.length; i++)
{
for (int j=0; j<Leaders[i].length; j++)
{
LeadersInOne.add(Leaders[i][j]);
}
}
ArrayAdapter<String> dataAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, LeadersInOne);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
leadersSpinner.setAdapter(dataAdapter);
}
这些是出现在 LogCat 中的错误详细信息:
01-20 18:41:02.712 16113-16113/com.example.atomi.scoutmanagerprototype E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.atomi.scoutmanagerprototype, PID: 16113
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.atomi.scoutmanagerprototype/com.example.atomi.scoutmanagerprototype.frmCreateEvent1}: java.lang.NullPointerException: Attempt to get length of null array
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2314)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
at android.app.ActivityThread.access$800(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5310)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at com.example.atomi.scoutmanagerprototype.frmCreateEvent1.loadSpinnerData(frmCreateEvent1.java:44)
at com.example.atomi.scoutmanagerprototype.frmCreateEvent1.onCreate(frmCreateEvent1.java:33)
at android.app.Activity.performCreate(Activity.java:5953)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1128)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2267)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
at android.app.ActivityThread.access$800(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5310)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
有谁知道可能出了什么问题?这是我第一次在 Android Studio、Java 或 XML 中工作,我必须自学所有这些,所以非常感谢任何帮助。谢谢。
解决方案
我相信使用Cursor Adapter(例如SimpleCursorAdapter )会遇到更少的问题。游标适配器旨在处理游标,因此无需为数组适配器创建中间数组。他们还将ID传递给onItemSelected方法。但是,它们确实需要一个名为_id的列,它是id列(下面的示例显示了即使 id 列被命名为其他名称也可以做到这一点)。
例子
以下示例基于您的代码。它选择在部分列中具有领导者的侦察员来填充微调器。它还包括一个onItemSelected侦听器,该侦听器会在选择侦察员时通过吐司显示侦察员的详细信息。
- 为了方便/解释/演示使用多列,使用了布局 simple_list_item_2。
数据库助手.java
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "mydatabase";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_EVENTS = "events";
private static final String COLUMN_SEID = BaseColumns._ID; //<<<<<<<<<< suits Cursor Adaptor
private static final String COLUMN_SNAME = "sname";
private static final String COLUMN_STYPE = "stype";
private static final String COLUMN_SDATE = "sdate";
private static final String COLUMN_EDATE = "edate";
private static final String COLUMN_STIME = "stime";
private static final String COLUMN_ETIME = "etime";
private static final String COLUMN_VENUE = "venue";
private static final String COLUMN_DESC = "desccription";
private static final String COLUMN_SCID = "scid";
private static final String COLUMN_EMAIL = "email";
private static final String COLUMN_ACOST = "acost";
private static final String COLUMN_INV = "inv";
private static final String COLUMN_PCOST = "pcost";
private static final String COLUMN_FOOD = "food";
private static final String COLUMN_TINC = "tinc";
private static final String COLUMN_DIST = "dist";
private static final String COLUMN_TCOST = "tcost";
public static final String TABLE_SCOUTS = "scouts"; //<<<<<<<<<<< public so the can be used elsewhere
public static final String COLUMN_FNAME = "fname";
public static final String COLUMN_LNAME = "lname";
public static final String COLUMN_SECTION = "section";
SQLiteDatabase mDB;
private static final String CREATE_TABLE_EVENTS=("CREATE TABLE " + TABLE_EVENTS + "("
+ COLUMN_SEID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_SNAME + " TEXT,"
+ COLUMN_STYPE + " TEXT,"+ COLUMN_SDATE + " TEXT," + COLUMN_EDATE + " TEXT,"
+ COLUMN_STIME + " TEXT," + COLUMN_ETIME + " TEXT," + COLUMN_VENUE + " TEXT,"
+ COLUMN_DESC + " TEXT," + COLUMN_SCID + " INTEGER," + COLUMN_EMAIL + " TEXT,"
+ COLUMN_ACOST + " REAL," + COLUMN_INV + " INTEGER," + COLUMN_PCOST + " REAL,"
+ COLUMN_FOOD + " TEXT," + COLUMN_TINC + " TEXT," + COLUMN_DIST + " INTEGER,"
+ COLUMN_TCOST + " REAL )");
private static final String CREATE_TABLE_SCOUTS = "CREATE TABLE " + TABLE_SCOUTS + "(" +
COLUMN_SCID + " INTEGER PRIMARY KEY," +
COLUMN_FNAME + " TEXT," +
COLUMN_LNAME + " TEXT," +
COLUMN_SECTION + " TEXT" +
")";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_EVENTS);
db.execSQL(CREATE_TABLE_SCOUTS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long addScout(String fname, String lname, String section) {
ContentValues cv = new ContentValues();
cv.put(COLUMN_FNAME,fname);
cv.put(COLUMN_LNAME,lname);
cv.put(COLUMN_SECTION,section);
return mDB.insert(TABLE_SCOUTS,null,cv);
}
public Cursor getLeaders() {
String where_clause = COLUMN_SECTION + "=?";
String[] where_args = new String[]{"Leaders"};
//<<<<<<<<<< NOTE SELECT scid AS _id, fname, lname, section so that the id column in the cursor is _id
String[] columns = new String[]{COLUMN_SCID + " AS " + BaseColumns._ID,COLUMN_FNAME, COLUMN_LNAME,COLUMN_SECTION};
return mDB.query(TABLE_SCOUTS,columns,where_clause,where_args,null,null,null);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
Spinner leadersSpinner;
SimpleCursorAdapter leaderAdapter;
Cursor leaders;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
databaseHelper = new DatabaseHelper(this); //<<<<<<<<<< prepre to use Database
leadersSpinner = this.findViewById(R.id.leaders_spinner); //<<<<<<<<<< get the Spinner
addSomeScoutsForTesting(); //<<<<<<<<<< Add some data for testing
setOrRefreshSpinner(); //<<<<<<<<<< prepare the spinner
}
@Override
protected void onDestroy() {
super.onDestroy();
leaders.close(); //<<<<<<<<<< Close the Cursor when the activity is done with
}
private void setOrRefreshSpinner() {
leaders = databaseHelper.getLeaders();
if (leaderAdapter == null) {
String[] columns = new String[]{DatabaseHelper.COLUMN_FNAME, DatabaseHelper.COLUMN_LNAME};
leaderAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_2,leaders,columns,new int[]{android.R.id.text1,android.R.id.text2},0);
leadersSpinner.setAdapter(leaderAdapter);
leadersSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String fname = leaders.getString(leaders.getColumnIndex(DatabaseHelper.COLUMN_FNAME));
String lname = leaders.getString(leaders.getColumnIndex(DatabaseHelper.COLUMN_LNAME));
Toast.makeText(
context,
"You clicked the Scout " +
fname + " " + lname +
" whoose ID is " + String.valueOf(l) +
" at position " + String.valueOf(i) +
" in the Spinner.",
Toast.LENGTH_SHORT
).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
} else {
leaderAdapter.swapCursor(leaders);
}
}
private void addSomeScoutsForTesting() {
// Only add if there are none
if (DatabaseUtils.queryNumEntries(databaseHelper.getWritableDatabase(),databaseHelper.TABLE_SCOUTS) > 0) return;
databaseHelper.addScout("Tony","Smith","Leaders");
databaseHelper.addScout("Anne","Taylor","Something else");
databaseHelper.addScout("Mary","Bloggs","Leaders");
databaseHelper.addScout("Sue","Franks","Leaders");
databaseHelper.addScout("Alan","Jones","Cubs Scouts");
databaseHelper.addScout("Belinda","Forrestor","Venturers");
}
}
- 注意添加了一些评论
推荐阅读
- python - 在二维数组上使用 scipy 实现三次插值
- javascript - 如何在反应中创建动画平滑的粘性标题
- php - 导入帖子时的 Wordpress 自定义分类
- docker - 使用 docker compose 运行 Apache Skywalking 的问题
- linux - 请求 'gl >= 9.2.0' 但 GL 版本是 1.2 xorg-server
- amazon-web-services - 如何使用计划/延迟事件实现事件驱动架构?
- python - 如何从图中确定节点的入度和出度?
- php - 为什么最后一个命令没有执行?
- python - 删除二叉树中的一个分支(链表实现)
- reactjs - 使用 react-router useHistory 钩子通过新的查询参数导航到当前路由