Ошибка загрузки записей базы данных в Spinner - PullRequest
0 голосов
/ 20 января 2019

Я работаю над приложением для моего курса по компьютерным наукам уровня 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;
}

Причина, по которой я использую 2d-массив, заключается в том, что позже я хочу иметь возможность вернуться и получить более подробную информацию об этом лидере - однако это будет на другом экране и, следовательно, в другом классе. Поэтому я хотел иметь возможность сохранять все детали по отдельности.

Вот код, который я написал, чтобы поместить все значения в счетчик:

    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) 

1012 *

Кто-нибудь знает, что могло пойти не так? Я впервые работаю в Android Studio, Java или XML, и мне приходится учить их всех, поэтому любая помощь будет принята с благодарностью. Спасибо.

1 Ответ

0 голосов
/ 21 января 2019

Я полагаю, что у вас будет меньше проблем с использованием Cursor Adapter , например SimpleCursorAdapter .Адспаторы курсоров предназначены для работы с курсорами, поэтому нет необходимости создавать промежуточный массив для адаптера массива.Они также передают ID методу onItemSelected .Однако им требуется столбец с именем _id , то есть столбец id (в приведенном ниже примере показано, как это можно сделать, даже если в столбце id указано другое имя).

Пример

Следующий пример основан на вашем коде.Он выбирает разведчиков, которые имеют Лидеры в столбце раздела, чтобы заполнить счетчик.Он также включает в себя прослушиватель onItemSelected , который приводит к отображению сведений о скауте через тост при выборе скаута.

  • Для удобства / объяснения / демонстрации использования нескольких столбцовиспользовался макет simple_list_item_2.

Databasehelper.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");
    }
}
  • Обратите внимание, некоторые комментарии были добавлены
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...