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