Created
June 21, 2018 10:46
-
-
Save niwatako/dab3458aa88caecf40568e05992e8e5e to your computer and use it in GitHub Desktop.
yaraki さん 〜Roomのできるまで 〜InvalidationTracker編〜 #CodePiece #potatotips
This file contains hidden or 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
potatotips #52 (iOS/Android開発Tips共有会) - connpass | |
https://potatotips.connpass.com/event/88164/ | |
## yaraki さん 〜Roomのできるまで 〜InvalidationTracker編〜 | |
初 #potatotips です。 | |
@yuichi_araki Google Developer Relations | |
AndroidのサポートライブラリやRoomを作っています。 | |
RoomはAndroidに標準搭載されたSQLiteのラッパー。アノテーションプロセッサーで実装を生成する。SQLを隠蔽していないので、SQLを書いてください、書いてくれたらいい感じにしますという方式。 | |
@Dao | |
interface UserDao { | |
@Query("Select * FROM User") | |
fun all(): LiveData<List<User>> | |
} | |
val users = userDao.all() | |
viewModel.users.observe(this, | |
クエリの結果がカーソルとして帰ってきてオブジェクトのリストにして返すだけなのだけれど、テーブルを見てるObserverのところで、変更があったらInvalidate()(クエリ呼び直し)を呼ぶ。 | |
そもそもSQLiteからどうやって通知を受けているのか | |
実装の考え方 | |
書き込みメソッドの実装もRoomが生成しているので、自分で通知できる | |
@Insert | |
void insert(User: user); に渡すとInsertされるのだけど、 | |
実際のInsert処理: `__insertionAdapterOfUser.insert(user)` | |
この中で書き換えたらいいじゃない | |
でも、API上、SQLiteにちょくで書き込むことができるようになってしまっているので、直接触られると検知できない。また、SQLiteのトリガーという機能で自動で書き込まれた内容も検知できない。 | |
探すとよくできている便利機能がある。 | |
C言語からSQLite使うときの拡張機能で、変更が全部来る | |
`void *sqlite3_update_hook()` というのがある。 | |
最強に思えるが、APIを呼ぶ口が用意されていなくて、Andoroidでは使えない。 | |
ではどうしたか | |
トリガーを使うことにした。変更ログ用のテーブルをシステムテーブルとして用意する。 | |
各テーブルに変更があるたびに経校ログが記入されるようなトリガーをこっそり仕掛ける。 | |
トランザクション終了時にそのログを確認する。 | |
Roomではすべての書き込みはトランザクションで処理する。 | |
Roomに通知する。 | |
UpdateとDelete用のトリガーも作る。 | |
``` | |
database.invalidationTracker.addObserver(object: InvalidationTracker.Observer("User") { | |
override fun onInvalidated(tables:... | |
} | |
``` | |
トリガーを監視していないテーブルに仕掛けるのは無駄。 | |
動的に、監視されているときだけトリガーをつける。ObservedTableTrackerの中にある仕組み。 | |
### 今後の課題 | |
2.0?次のバージョンでは、インスタンスやプロセスをまたぐと動かないとか、他のスレッドが長時間書き込んでいる途中は新規のObserverを開始できないとかのあたりをなんとかしたい。 | |
ワークアラウンドとしては、長いトランザクションの先にDummyのObserverを仕掛けておくといいぞ。 | |
不具合報告、要望は issuetracker.google.com から |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment