Мой запрос Android SQLite DB не возвращает недавно вставленные данные, пока я не выйду из своей активности и не перезапущу

Я использую базу данных SQLite в своем приложении для Android, чтобы хранить футболистов и поддерживать их составы. Действие, которое управляет этими списками, имеет возможность открывать 2 диалоговых окна: 1 для сохранения текущего списка в базу данных и 1 для загрузки существующего списка из базы данных.

Когда список сохраняется, а затем открывается диалоговое окно для загрузки списка, вновь сохраненный список не обнаруживается в моем запросе существующих списков. Если я выйду из занятия и перезапущу его, новый список появится в списке и его можно будет загрузить нормально.

Вот код, который запрашивает у БД существующие имена реестров.

public String[] fetchRosterNames() {        

    String query = "SELECT "+ _ID + ", " + ROSTER_NAME + ", COUNT(" + ROSTER_NAME + ") As `NUM_PLAYERS`" +
            " FROM " + TABLE_NAME + 
            " GROUP BY " + ROSTER_NAME;
    SQLiteDatabase db = getReadableDatabase();
    Cursor cursor = db.rawQuery(query, null);

    ArrayList<String> rosterNames = new ArrayList<String>();
    if(cursor.getCount() > 0){
        while(!cursor.isLast()){
            cursor.moveToNext();
            rosterNames.add(cursor.getString(1));
        }
    }       
    cursor.close();
    db.close();
    return rosterNames.toArray(new String[rosterNames.size()]);
}

вот код, который вставляет список в общедоступную базу данных void insertRoster (String roster_name, LeagueRoster roster) {

    SQLiteDatabase db = getWritableDatabase();
    Iterator<Player> players = roster.getFullRoster();

    while(players.hasNext()){

        Player player = players.next();         

        ContentValues values = new ContentValues();
        Log.e("MySQLiteHelper: insertRoster()", player.getName());

        values.put(PlayerStats.NAME.name(), player.getName());
        values.put(PlayerStats.POSITION.name(), player.getPosition().name());
        values.put(PlayerStats.TEAM.name(), player.getTeam().name());           
        values.put(ROSTER_NAME, roster_name);   

        db.insertOrThrow(TABLE_NAME, null, values);
    }

    db.close();
}

И, наконец, вот код в моей деятельности, который создает 2 разных диалоговых окна.

protected Dialog onCreateDialog(int id){

    AlertDialog.Builder builder = new AlertDialog.Builder(this);

    switch(id) {
    case 1:         
        final MySQLiteHelper rosterData = new MySQLiteHelper(this);
        final String[] items = rosterData.fetchRosterNames();
        builder.setTitle("Select the roster you would like to load");
        builder.setItems(items, new DialogInterface.OnClickListener(){

            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.e("Roster Names Dialog", items[which]);
                LeagueRoster loadedRoster = rosterData.fetchRoster(items[which]);
                if(loadedRoster != null){
                    roster = loadedRoster;
                    db.setRoster(roster);
                    redrawTables();
                }
            }               
        });

        dialog = builder.create();
        break;
    case 2:
    default:
        LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
        View saveRosterView = inflater.inflate(R.layout.saveroster_dialog, null);
        builder.setView(saveRosterView);

        final EditText nameField = (EditText)saveRosterView.findViewById(R.id.saveroster_dialog_editText);
        Button saveButton = (Button)saveRosterView.findViewById(R.id.saveroster_dialog_button);

        saveButton.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                MySQLiteHelper rosterData = new MySQLiteHelper(RosterActivity.this);
                String rosterName = nameField.getText().toString();
                rosterData.insertRoster(rosterName, roster);
                dialog.dismiss();
            }               
        });

        dialog = builder.create();
        break;
    }
    return dialog;
}

Я был бы очень признателен за помощь с этой проблемой, если у кого-то есть идеи ...


person Arutal    schedule 30.05.2012    source источник
comment
Способ получения имен списков из Курсора действительно слишком сложен. Вы можете сделать это намного проще. См. stackoverflow.com/a/10723771/385478   -  person Graham Borland    schedule 30.05.2012
comment
Спасибо за совет, выглядит намного чище   -  person Arutal    schedule 30.05.2012


Ответы (2)


Хорошо, я разобрался с проблемой. Это связано с тем, как Android обрабатывает диалоги, а не с SQLite. Из документации Android ...

http://developer.android.com/guide/topics/ui/dialogs.html

Если вы используете onCreateDialog (int) для управления состоянием ваших диалогов (как обсуждалось в предыдущем разделе), то каждый раз, когда ваш диалог закрывается, состояние объекта Dialog сохраняется в Activity. Если вы решите, что вам больше не нужен этот объект или важно, чтобы состояние было очищено, вам следует вызвать removeDialog (int). Это удалит> любые внутренние ссылки на объект и, если отображается диалоговое окно, отклонит его.

Убедившись, что диалоговое окно полностью воссоздавалось каждый раз, когда моя кнопка загрузки была нажата, проблема была решена. Ранее запрос SQLite не запускался повторно и поэтому не мог предоставить диалоговому окну новые данные.

Спасибо всем за помощь!

person Arutal    schedule 30.05.2012

Странно, но пробовать db.commit () после каждой вставки?

person Torp    schedule 30.05.2012
comment
SQLiteDatabase, похоже, не имеет метода commit () - person Arutal; 30.05.2012
comment
Нет, это endTransaction (). Я столкнулся с этой проблемой, но не в Android, просто с несколькими процессами unix, попадающими в одну и ту же базу данных. Я думаю, что решил эту проблему, разбросав коммиты. - person Torp; 30.05.2012
comment
Я попытался поставить beginTransaction () перед вставкой и setTransactionSuccessful () и endTransaction () после, но, похоже, это не решило проблему. - person Arutal; 30.05.2012
comment
Жаль, что нет идей в банкомате. Но я уверен, что скоро придет кто-то, кто действительно решил вашу проблему. - person Torp; 30.05.2012