アプリをリリースしようとしてtargetSdkVersionを26にするとActiveAndroidが動かない事態になりました。
どうやらメンテナンスされてないためまともに動かないご様子。
https://www.tsurutan.com/entry/2018/10/08/Migration_ActiveAndroid_to_Room
https://qiita.com/pside/items/03e6256b404c75f5974b#activeandroid%E3%81%AE%E7%A7%BB%E8%A1%8C%E3%83%91%E3%82%B9%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AEreactiveandroid
既存の記述も結構な量があり、完全に新規のライブラリに移行するのがきつかったので結構な互換性がある
ReActiveAndroidに移行
(新規だともっと選択の余地があります。Roomとか…)
下記そのときの対応メモです
需要があるかどうかは全くわかりませんが同じことで困ってる人の助けになれば…
対応
下記ドキュメントの通りに対応する
https://imangazalievm.gitbooks.io/reactiveandroid/migration-from-activeandroid.html
DB名とテーブル名はそれぞれDbName
、TableName
に書き換えてます。
-
build.gradle
に
implementation 'com.reactiveandroid:reactiveandroid:1.4.3'
implementation 'android.arch.persistence:db:1.1.1'
を追記。
-
DbName.java
を作成、@Database(name = "DbName", version = 1)
と下記マイグレーションメソッドを記述。
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
// Since we didn't alter the table, there's nothing else to do here.
}
};
- App.javaの初期化部分から下記の形で呼び出す
DatabaseConfig appDatabaseConfig = new DatabaseConfig.Builder(DbName.class)
.addMigrations(DbName.MIGRATION_1_2)
.build();
ReActiveAndroid.init(new ReActiveConfig.Builder(this)
.addDatabaseConfigs(appDatabaseConfig)
.build());
- ソースコード内の
activeandroid
のimport文を全て消してreactiveandroid
の方をimportする。ディレクトリ構成は変わってないので、activeandroid
の部分をreactiveandroid
に置き換えでいけるはず。 - プライマリキーに
@PrimaryKey(name = "id")
を追記する。 - 各ModelクラスのTableのアノテーションを
@Table( name = "tableName", database = DbName.class)
に変更 - 下記の通りメソッド呼び出しの構文を変更
-
new Select()
をSelect
に変更 -
executeSingle
をfetchSingle
に変更 -
execute
をfetch
に変更
-
こんな感じ⬇︎
- new Select().from(TableName.class).where("Id = %d".format(id)).executeSingle[TableName]();
+ Select.from(TableName.class).where("Id = %d".format(id)).fetchSingle();
-
exist()
にあたるメソッドが見当たらないので、count() > 0
で判定する。 (パフォーマンスに影響出るかもなので確認。出そうだったらlimitをつける) - ActiveAndroidで標準装備されてたgetId()とかのgetter/setterはReActiveAndroidでは存在しないので、必要なら自分で追記する
- transactionの記述を変更
- ActiveAndroid.beginTransaction();
- ActiveAndroid.setTransactionSuccessful();
- ActiveAndroid.endTransaction();
+ ReActiveAndroid.getDatabase(DbName.class).beginTransaction();
+ ReActiveAndroid.getDatabase(DbName.class).getWritableDatabase().setTransactionSuccessful();
+ ReActiveAndroid.getDatabase(DbName.class).endTransaction();
ここまでやったら動くはず…
引っかかったところメモ
上記手順通りにやったら出ないはずです。
Please provide a Migration
Please provide a Migration in the builder or call disableMigrationsChecking in the builder in which case ReActiveAndroid will re-create all of the tables.
マイグレーション処理を書き忘れてたのが原因
>上記手順の通りにマイグレーションメソッドを追加、呼び出ししたら解消
SupportSQLiteDatabaseが解決されない
https://mvnrepository.com/artifact/android.arch.persistence/db
でバージョンを確認、
implementation 'android.arch.persistence.db:1.1.1'
をgradleに追加
>Error:Failed to resolve: android.arch.persistence.db:1.1.1:
のエラー。
>http://fengwanxingzhou.coding.me/Android%E9%94%99%E8%AF%AF/
パッケージ名の指定が間違ってるっぽい。
android.arch.persistence:db:1.1.1
にしたら通った。
Couldn't read row 0, col -1 from CursorWindow
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
ActiveAndroidではCursorを使わず記述できるのでどっかの内部処理で使ってるはず。
>エラー箇所(Select
)の内部処理を見てもcursorを使ってるところが見当たらない…
>fetchSingle
の内部(Tableの定義を持ってきているところ)で使われてた。
>ここにブレークポイントを貼ってみると、idName
が"_id"
のカラムを持ってこようとしていた。
テンプレをそのまま持ってきて@PrimaryKey(name = "_id")
としたのが原因。(本当のカラム名はId
)
なので
- @PrimaryKey(name = "_id")
+ @PrimaryKey(name = "Id")
と修正して解消。