2010-04-27 2 views
1

У меня есть приложение для Android, которое вытаскивает случайные 20 вопросов (строк) в качестве курсора из базы данных SQLite и перебирает все вопросы, чтобы задать пользователю все 20 вопросов.Сохранение состояния курсора с помощью экземпляра активности?

Есть ли способ сохранить состояние/местоположение курсора при приостановке или остановке действия, чтобы при возобновлении действия курсор восстанавливался и находился в том же положении, в каком оно было, когда действие приостанавливалось/останавливалось?

Если вам нужно, чтобы я опубликовал свой код, просто спросите.

Спасибо за ваше время!

ответ

2

Получение его, чтобы сохранить положение это было в очень легко, просто поместите код в методе OnPause следующим образом:

protected void onPause(){ 
position = yourCursor.getPosition(); 
super.onPause(); 
} 

, где положение является полем класса (т.е. объявлен вне какого-либо метода, как правило, на вершине). Затем в onResume вы можете просто переместить курсор обратно в эту позицию. Если вы не знакомы с onPause()/onResume(), прочитайте на activity lifecycle. Тем не менее, я подозреваю, что вы хотите сохранить, какие вопросы были случайно выбраны. Я не думаю, что ваш курсор будет сохраняться в onPause/onResume, поскольку они вообще закрыты в onPause, чтобы избежать проблем с памятью. Единственное, о чем я могу думать, но я не эксперт, это то, что вам нужно будет сохранить идентификаторы rowID вопросов, а затем запросить базу данных, чтобы получить эти строки. Насколько неуклюжее это решение зависит от того, как вы запрашиваете случайные вопросы в первую очередь. Если вы уже генерируете 20 случайных чисел и затем загружаете их в свой запрос, вы можете просто повторно использовать один и тот же метод, но с 20 сохраненными строками.


Это было слишком долго, чтобы соответствовать как комментарий:

@Ryan: Действительно, сохранение позиции без состояния курсора довольно бесполезно, если вы не можете воссоздать идентичную курсор - это то, что я говоря во второй половине моего ответа. Я предполагаю, что ваш RANDOM() является стандартной функцией SQL? (Каков синтаксис для Android в Android-формате? Я не мог заставить свою базу данных принять его.) Если это так, вам может понадобиться сделать метод грубой силы, чтобы воссоздать ваш курсор. Под этим я имею в виду запрос базы данных с «rowId =? OR rowId =? OR rowId =? ИЛИ ....» с аргументами выбора, которые являются строками, которые вы извлекали из исходного курсора. Это некрасиво, и, вероятно, есть лучший способ сделать это, но это сработает. Построение выберитеСтроковый будет легко с петлей так:

String selectQuery = ""; 
String[] selectArgs = new String[savedRows.length]; 
for (int i = 0; i < savedRows.length; i++){ 
    selectQuery = selectQuery.concat("rowID = ? OR "); 
    selectArgs[i] = Long.toString(savedRows[i]); 
} 

//Remove the last " OR " you'd have in the string 
int index = selectQuery.lastIndexOf(" OR "); 
selectQuery = selectQuery.substring(0, index); 

Это при условии, что вы сохраните ROWIDs от исходного курсора в long[] savedRows в методе OnPause. Затем вы можете передать их в новый запрос базы данных.


Опять же, слишком долго для комментариев:

@Ryan: Хороший вопрос, они не могли бы втянуты обратно в том же порядке. Вы могли бы поэкспериментировать, но было бы трудно сказать, было ли это случайностью или по дизайну, что он всегда возвращался в том же порядке. Итак, идея номер 3 затем создает промежуточную таблицу, заполненную 20 случайными вопросами. В этой таблице будет столбец для номера строки (дающий вам порядок вопросов), а затем столбец внешнего ключа с rowId вопроса в таблице вопросов. Получить ваши вопросы в том же порядке из этой таблицы было бы легко, и вы могли бы отказаться от таблицы, как только пользователь закончит все вопросы. Или вы могли бы даже держать таблицу так, чтобы пользователь мог видеть, насколько хорошо они выполнялись на прошлых наборах вопросов, но это совершенно другая особенность.

Примечание: Я должен был упомянуть onSaveInstanceState, а также в моем первом сообщении. onPause - хорошее место для быстрого сохранения, прежде чем изменять действия, но просто сохранить позицию в int не является надежным. Очевидно, он сбрасывается, когда пользователь начинает новую викторину (как и должно), но он также сбрасывается, если пользователь просматривает другое действие, ОС должна была убить ваш процесс для памяти. В этом случае, когда пользователь возвращается к активности, он должен перезапускаться из onCreate и, следовательно, теряет переменные данные. Это предназначено для работы с методом onSaveInstanceState(), который снабжает вас пакетом, в который вы можете сохранить свои данные. Этот же Bundle затем поставляется в onCreate, позволяя вам перезагрузить все необходимое и заставить его выглядеть так, как приложение никогда не было убито.

+0

@Steve H: Спасибо за ответ. Я на самом деле заполняю курсор, используя метод запроса класса SQLiteDatabase, который принимает предельный параметр. Я передаю в RANDOM() для порядка по параметру и 20 для предельного параметра. Я не уверен, что сохранение положения курсора сделает мне много хорошего, не сохраняя фактический порядок строк курсора. Следовательно, мне нужно сохранить состояние самого курсора. – Ryan

+0

@Steve H: Да, RANDOM() работает как стандартная функция в базе данных SQLite. Попробуйте выполнить этот запрос «ВЫБЕРИТЕ * ОТ НЕКОТОРНОГО ЗАКАЗА ПО RANDOM()». Я вижу, что вы говорите, но если строки не возвращаются в том порядке, в котором их вытаскивает оригинальный курсор, я не думаю, что то, что вы говорите, поможет в этом случае? Я вытащил 20 случайных вопросов, тогда действие приостанавливается/останавливается на вопросе 5. Когда я возобновляю действие и снова вытягиваю строки, строки будут вытаскиваться в том же порядке, в котором они были первоначально, используя ваш метод выше? – Ryan

+1

@Steve H: Мне очень нравится идея временного стола. Однако, я думаю, я должен был упомянуть, что я беспокоюсь только о сохранении состояния курсора при изменении ориентации телефона. Я нашел еще одно сообщение о переполнении стека, которое ссылается на использование onRetainNonConfigurationInstance(), и это работает как мечта о том, что мне нужно, хотя я могу закончить настройку своего приложения, чтобы в конечном итоге использовать идею temp table. Спасибо за помощь! – Ryan