-
-
Save hkusu/8dfc3b84406bf32be567 to your computer and use it in GitHub Desktop.
例
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.github.hkusu.realmtodoapp; | |
import android.os.Handler; | |
import android.os.HandlerThread; | |
import java.util.List; | |
import de.greenrobot.event.EventBus; | |
import io.realm.Realm; | |
import io.realm.RealmResults; | |
/** | |
* Todoデータ操作モデルクラス | |
*/ | |
public class TodoModel { | |
/** シングルトンインスタンス */ | |
private static final TodoModel INSTANCE = new TodoModel(); | |
/** Realmのインスタンス(参照用) */ | |
private final Realm mRealmForSelect = Realm.getDefaultInstance(); | |
/** Realmのインスタンス(更新用) */ | |
private Realm mRealmForUpdate; | |
/** 更新(登録・削除)用スレッドへメッセージを送るためのハンドラ */ | |
private final Handler mHandler; | |
private final RealmWrapper mRealmWrapper = new RealmWrapper(); | |
/** | |
* 利用元にシングルトンインスタンスを返す | |
* | |
* @return Todoデータ操作モデルのインスタンス | |
*/ | |
public static TodoModel getInstance() { | |
return INSTANCE; | |
} | |
/** | |
* コンストラクタ *外部からのインスタンス作成は禁止* | |
*/ | |
private TodoModel() { | |
// 更新用スレッドを起動 | |
HandlerThread handlerThread = new HandlerThread("realm"); | |
handlerThread.start(); | |
// ハンドラを取得 | |
mHandler = new Handler(handlerThread.getLooper()); | |
} | |
/** | |
* Todoデータ全件を取得(降順) | |
* | |
* @return TodoデータのList(RealmResult型であるためDBの変更内容は動的に反映される) | |
*/ | |
public List<TodoEntity> get() { | |
return mRealmForSelect.allObjectsSorted(TodoEntity.class, TodoEntity.SORT_KEY, RealmResults.SORT_ORDER_DESCENDING); | |
} | |
/** | |
* idをキーにTodoデータを取得 ※現状は未使用* | |
* | |
* @param id 検索対象のTodoデータのid | |
* @return Todoデータ(1件) | |
*/ | |
public TodoEntity getById(int id) { | |
return mRealmForSelect.where(TodoEntity.class) | |
.equalTo(TodoEntity.PRIMARY_KEY, id) | |
.findFirst(); | |
} | |
/** | |
* Todoデータを登録 | |
* | |
* @param todoEntity 登録するTodoデータ | |
* @return 成否 | |
*/ | |
public boolean createOrUpdate(final TodoEntity todoEntity) { | |
if (todoEntity.getId() == 0) { | |
// 登録されているTodoデータの最大idを取得し、+1 したものをidとする(つまり連番) | |
todoEntity.setId(getMaxId() + 1); | |
} | |
// // 別スレッドで実行 | |
// mHandler.post(new Runnable() { | |
// @Override | |
// public void run() { | |
// // Realmのインスタンスはこのスレッドの中で取得する | |
// if (mRealmForUpdate == null) { | |
// mRealmForUpdate = Realm.getDefaultInstance(); | |
// } | |
// // トランザクション開始 | |
// mRealmForUpdate.beginTransaction(); | |
// try { | |
// // idにプライマリキーを張ってあるため既に同一idのデータが存在していれば更新となる | |
// mRealmForUpdate.copyToRealmOrUpdate(todoEntity); | |
// // コミット | |
// mRealmForUpdate.commitTransaction(); | |
// // データが変更された旨をEventBusで通知 | |
// EventBus.getDefault().post(new ChangedEvent()); | |
// } catch (Exception e) { | |
// // ロールバック | |
// mRealmForUpdate.cancelTransaction(); | |
// } | |
// } | |
// }); | |
mRealmWrapper.exec(new RealmOperation() { | |
@Override | |
public void transaction(Realm realm) { | |
mRealmForUpdate.copyToRealmOrUpdate(todoEntity); | |
} | |
@Override | |
public void afterExec(boolean success) { | |
if (success) { | |
EventBus.getDefault().post(new ChangedEvent()); | |
} | |
} | |
}); | |
return true; | |
} | |
/** | |
* idをキーにTodoデータを削除 | |
* | |
* @param id 削除対象のTodoデータのid | |
* @return 成否 | |
*/ | |
public boolean removeById(final int id) { | |
// 別スレッドで実行 | |
mHandler.post(new Runnable() { | |
@Override | |
public void run() { | |
// Realmのインスタンスはこのスレッドの中で取得する | |
if (mRealmForUpdate == null) { | |
mRealmForUpdate = Realm.getDefaultInstance(); | |
} | |
// トランザクション開始 | |
mRealmForUpdate.beginTransaction(); | |
try { | |
// idに一致するレコードを削除 | |
mRealmForUpdate.where(TodoEntity.class).equalTo(TodoEntity.PRIMARY_KEY, id).findAll().clear(); | |
// コミット | |
mRealmForUpdate.commitTransaction(); | |
// データが変更された旨をEventBusで通知 | |
EventBus.getDefault().post(new ChangedEvent()); | |
} catch (Exception e) { | |
// ロールバック | |
mRealmForUpdate.cancelTransaction(); | |
} | |
} | |
}); | |
return true; | |
} | |
/** | |
* Todoデータの件数を取得 | |
* | |
* @return 件数 | |
*/ | |
public int getSize() { | |
return mRealmForSelect.allObjects(TodoEntity.class).size(); | |
} | |
/** | |
* 登録されているTodoデータの最大idを取得 | |
* | |
* @return 最大id | |
*/ | |
private int getMaxId() { | |
return mRealmForSelect.where(TodoEntity.class).findAll().max(TodoEntity.PRIMARY_KEY).intValue(); | |
} | |
/** | |
* Realmの接続を切断 *以降は利用できなくなるので注意* | |
*/ | |
public void closeRealm() { | |
mRealmForSelect.close(); | |
mRealmForUpdate.close(); | |
} | |
/** | |
* EventBus用のイベントクラス | |
*/ | |
public static class ChangedEvent { | |
// 特に渡すデータは無し | |
private ChangedEvent() { | |
} | |
} | |
} | |
class RealmWrapper { | |
/** 更新(登録・削除)用スレッドへメッセージを送るためのハンドラ */ | |
private final Handler mHandler; | |
/** | |
* コンストラクタ *外部からのインスタンス作成は禁止* | |
*/ | |
public RealmWrapper() { | |
// 更新用スレッドを起動 | |
HandlerThread handlerThread = new HandlerThread("realm"); | |
handlerThread.start(); | |
// ハンドラを取得 | |
mHandler = new Handler(handlerThread.getLooper()); | |
} | |
public void exec(final RealmOperation operation) { | |
// 別スレッドで実行 | |
mHandler.post(new Runnable() { | |
@Override | |
public void run() { | |
// Realmのインスタンスはこのスレッドの中で取得する | |
Realm realm = Realm.getDefaultInstance(); | |
// トランザクション開始 | |
realm.beginTransaction(); | |
try { | |
operation.transaction(realm); | |
// コミット | |
realm.commitTransaction(); | |
// この実行は MainThreadでやっても良いと思います(そのほうが親切っぽい) | |
operation.afterExec(true); | |
} catch (Exception e) { | |
// ロールバック | |
realm.cancelTransaction(); | |
// この実行は MainThreadでやっても良いと思います(そのほうが親切っぽい) | |
operation.afterExec(true); | |
} | |
} | |
}); | |
} | |
} | |
interface RealmOperation { | |
void transaction(Realm realm); | |
void afterExec(boolean success); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment