Realmのマイグレーションを以下のように別スレッドで実行したところエラーが出てクラッシュした。
StartActivity.java
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
//-- 中略 --
//DBのupdate
new Thread(mCheckAndUpdate).start();
}
Runnable mCheckAndUpdate = new Runnable() {
@Override
public void run() {
//初回起動時の色々update処理
//...
//Migration check
//filecheck
File filesDir = getFilesDir();
for(String file : filesDir.list()){
if(file.equals(REALM_DBNAME)){
//RealmのDBが会った場合はMigrationを実行
Realm.migrateRealmAtPath(getFilesDir() + "/"+ REALM_DBNAME,new MigrationManager());
});
}
}
//終わったらハンドラーでメッセージを送り画面遷移
mCheckHandler.sendMessage(mCheckHandler.obtainMessage(0, StartActivity.this));
}
};
メッセージ
IllegalStateException: cannot set auto-refresh in a thread without a looper
で、ソースコードを追っていったところ、メッセージにもあるようにlooperがないスレッドではmigrateRealmAtPathから呼んでいるsetAutoRefresh()というメソッドがexceptionをthrowするらしい。
なので、looperがあるUIthreadで処理を実行したら、うまく動いた。
StartActivity.java
Runnable mCheckAndUpdate = new Runnable() {
@Override
public void run() {
//初回起動時の色々update処理
//...
//Migration check
//filecheck
File filesDir = getFilesDir();
for(String file : filesDir.list()){
if(file.equals(REALM_DBNAME)){
runOnUiThread(new Runnable() {
@Override
public void run() {
Realm.migrateRealmAtPath(getFilesDir() + "/"+ REALM_DBNAME,new MigrationManager());
}
});
}
}
//終わったらハンドラーでメッセージを送り画面遷移
mCheckHandler.sendMessage(mCheckHandler.obtainMessage(0, StartActivity.this));
}
};
ただ、このやり方だとUIスレッドをめっちゃブロックするので、大きく構成変えるとかする場合は何か他の方法考えないと行けない気がする。