Android同時、マルチスレッド操作SQLiteデータベース処理UIメインスレッドブロックによるUIインタフェースの詰まり

1660 ワード

今日Androidプロジェクトにバグ(卵が痛くて私が書かないコード)があります.1つの業務が何度も頻繁に呼び出されると、メインスレッドui(主に時間)が詰まってしまいます.1つ1つのエラー位置を探すには、エラーの位置付けが重要です.
最初は問題点を見つけてメインスレッドを呼び出したHandler
Handler handler = new Handler(mContext.getMainLooper());
handler.post(........);

ピットの中にはネットリクエストなど時間のかかる操作もあります....
しかし、取り除いた後も問題は解決していないことに気づいた!最後に1つのモジュールを振り回して削除した後、問題を操作マルチスレッドSQLiteデータベースの上に配置しました.
マルチスレッド操作SQLiteには多くのソリューションがあります.私はAtomicInteger原子操作クラスを使用しました.彼はスレッドが安全で、マルチスレッドを制御する場合、SQLiteDatabaseの実力オブジェクトを1つしか手に入れません.SQLiteOpenHelperは、必ず単一のモードを使用して1つだけ存在することを前提としています.
コード:
private AtomicInteger mOpenCounter = new AtomicInteger();
private SQLiteDatabase myDataBase = null;

public synchronized SQLiteDatabase getSQLiteDatabase() {
	if (mOpenCounter.incrementAndGet() == 1) {
		myDataBase = SQLHelper.getWritableDatabase();

	}

	return myDataBase;
}

同じSQLiteDatabaseを入手した後も同様の方法でclose
	public synchronized void closeDatabase() {
		if (mOpenCounter.decrementAndGet() == 0) {
			myDataBase.close();
		}
	}

このようなテストの後、一定数のデータを処理した後に現れることがあります.
W/SQLiteConnectionPool: The connection pool for database '/data/data/com.wbm.app.pda/databases/xxxxx.db' 
has been unable to grant a connection to thread 163308 (Thread-163308) with flags 0x1 for 60.001003 seconds. Connections: 0 active, 1 idle, 0 available.
このような場合はSQLiteDatabaseを使用したトランザクションbeginTransactionがendTransactionがない前にデータベースクエリーなどを操作しているはずです
注意異常を制御するには、catchまたはfinallyでタイムリーなendTransactionとSQLiteDatabaseのクローズ操作(マルチスレッドの場合、つまり原子操作クラスを追加して制御するcloseメソッド、例えば上記のcloseDatabase)を行う必要があります.