Monthly Archives: Март 2014

Ошибка: Finalizing a Cursor that has not been deactivated or closed

Решил схалявить в коде, в итоге два часа убил, чтобы найти ошибку с курсором SQLite в Android. Текст ошибки:
Finalizing a Cursor that has not been deactivated or closed
Или
android.database.sqlite.DatabaseObjectNotClosedException: 
Application did not close the cursor or database object that was opened here
Изначально было понятно, что где-то не закрывается курсор. Перепроверил все курсоры, после использования все курсоры закрываются. Причем, стек ошибок показывал фрагмент, где именно ошибка, но понял это лишь под отладкой. Вот фрагмент косячного кода:
public int getBufferCount(){
	String sql = "SELECT COUNT(*) FROM " + TBL_BUFFER;
	Cursor cursor = db.rawQuery(sql, null);
	cursor.moveToFirst();
	if(!cursor.isAfterLast()){
		return cursor.getInt(0);//ошибка
	}
	cursor.close();
	return 0;
}
Т.е. я делал return cursor.getInt(0);, а курсор оставался открытым! Исправленный вариант №1:
public int getBufferCount(){
	String sql = "SELECT COUNT(*) FROM " + TBL_BUFFER;
	Cursor cursor = db.rawQuery(sql, null);
	cursor.moveToFirst();
	int ret = 0;
	if(!cursor.isAfterLast()){
		ret = cursor.getInt(0);
	}
	cursor.close();
	return ret;
}
Исправленный вариант №2:
public int getBufferCount(){
	String sql = "SELECT COUNT(*) FROM " + TBL_BUFFER;
	Cursor cursor = db.rawQuery(sql, null);
	cursor.moveToFirst();
	if(!cursor.isAfterLast()){
		try{
			return cursor.getInt(0);
		}finally{
			cursor.close();
		}
	}
	cursor.close();
	return 0;
}
p.s.: Всё, что имеет метод close(), должно быть closed!

НОК и НОД (lcm и gcd) на Java

НОД (Наибольший общий делитель) или gcd (Greatest Common Divisor) НОД - наибольшее число, которое является делителем одновременно для чисел a и b. Реализация (Алгоритм Евклида):
long gcd(long a,long b){
	return b == 0 ? a : gcd(b,a % b);		
}
Применение:
System.out.println(gcd(10,24));//результат: 2
System.out.println(gcd(12,24));//результат: 12
System.out.println(gcd(11,24));//результат: 1
НОК (Наименьшее общее кратное) или lcm (Least Common Multiple) НОК - наименьшее число, которое делится на a и b без остатка. НОК можно найти через НОД по следующей формуле: нок Реализация:
long lcm(long a,long b){
	return a / gcd(a,b) * b;
}
Примечание: a / gcd(a,b) * b более предпочтительно, чем a * b / gcd(a,b), т.к. во втором случае при больших числах переполнение случиться намного раньше. Применение:
System.out.println(lcm(3, 4));//результат: 12
System.out.println(lcm(3, 9));//результат: 9
System.out.println(lcm(5,12));//результат: 60