LoginSignup
0
0

More than 3 years have passed since last update.

ActiveAndroid => ReActiveAndroid 移行

Last updated at Posted at 2019-10-19

アプリをリリースしようとして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名とテーブル名はそれぞれDbNameTableNameに書き換えてます。

  • build.gradle
implementation 'com.reactiveandroid:reactiveandroid:1.4.3'
implementation 'android.arch.persistence:db:1.1.1'

を追記。

  • DbName.javaを作成、@Database(name = "DbName", version = 1)と下記マイグレーションメソッドを記述。
DbName.java
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の初期化部分から下記の形で呼び出す
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に変更
    • executeSinglefetchSingleに変更
    • executefetchに変更

こんな感じ⬇︎

- 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
なので

TableName.java
- @PrimaryKey(name = "_id")
+ @PrimaryKey(name = "Id")

と修正して解消。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0