There has been a crash around Realm in the development of Android apps.
Realm files were generated and modified in the following time series.
When testing the beta version, we confirmed that there were no crashes, so we released the beta version as a product version.
(The α version was used only for internal testing, and has not been released.)
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo {xxx}:io.realm.exception.RealmMigrationNeededException: Invalid type 'String' for field 'notifyAt' in existing Realm file.
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2482)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2545)
at android.app.ActivityThread.access$900 (ActivityThread.java:186)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1410)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:148)
at android.app.ActivityThread.main (ActivityThread.java:5636)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:620)
Caused byio.realm.exception.RealmMigrationNeededException: Invalid type 'String' for field 'notifyAt' in existing Realm file.
atio.realm.ChildNotificationEntityRealmProxy.validateTable (ChildNotificationEntityRealmProxy.java:270)
atio.realm.DefaultModuleMediator.validateTable (DefaultModuleMediator.java:83)
atio.realm.Realm.initializeRealm(Realm.java:342)
atio.realm.Realm.createAndValidate (Realm.java:299)
atio.realm.Realm.createInstance(Realm.java:278)
atio.realm.RealmCache.createRealmOrGetFromCache (RealmCache.java:143)
atio.realm.Realm.getDefaultInstance(Realm.java:209)
at(appname).models.ChildModel.findById(ChildModel.java:56)
at(appname).models.UserModel.getCurrentChild(UserModel.java:30)
at(appname).activities.LaunchActivity.sendLaunchScreen(LaunchActivity.java:70)
at(appname).activities.LaunchActivity.onCreate(LaunchActivity.java:39)
at android.app.Activity.performCreate (Activity.java:6315)
at android.app.instrumentation.callActivityOnCreate (instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2435)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2545)
at android.app.ActivityThread.access$900 (ActivityThread.java:186)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1410)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:148)
at android.app.ActivityThread.main (ActivityThread.java:5636)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:620)
I apologize for the inconvenience, but please let me know.
February 23, 2017
Additional Information
import android.util.Log;
importio.realm.DynamicRealm;
importio.realm.RealmMigration;
importio.realm.RealmSchema;
public class migration implements RealmMigration {
private static final String TAG = Migration.class.getName();
@ Override
public void migrate (final DynamicRealm, long oldVersion, long newVersion) {
Log.d(TAG, "realm migration version:" + String.valueOf(oldVersion)));
RealmSchema schema=realm.getSchema();
}
}
private static RealmConfiguration mDefaultConfig;
private static RealmConfiguration mReadOnlyConfig;
@RealmModule(classes={
ChildArticleEntity.class,
ChildEntity.class,
ChildNotificationEntity.class,
FavoriteArticleEntity.class,
ReadArticleEntity.class
})
public static class DefaultModule {
}
@RealmModule(classes={
ArticleEntity.class,
CategoryEntity.class,
DateEventEntity.class,
DaysOldEventEntity.class,
DaysOldNotificationEntity.class,
MonthsOldEventEntity.class,
MonthsOldNotificationEntity.class,
SuggestSearchWordEntity.class,
TimelineEntity.class
})
public static class ReadOnlyModule{
}
public static void setupDefaultRealm(){
if(mDefaultConfig==null){
mDefaultConfig=newRealmConfiguration.Builder()
.schemaVersion (CURRENT_SCHEME_VERSION)
.migration(new Migration())
.modules (new DefaultModule())
.build();
}
Realm.setDefaultConfiguration(mDefaultConfig);
}
public static Realm getReadonlyInstance(){
if(mReadOnlyConfig==null){
mReadOnlyConfig = new RealmConfiguration.Builder()
.name(READ_ONLY_FILE_NAME)
.schemaVersion (CURRENT_SCHEME_VERSION)
.migration(new Migration())
.modules(new ReadOnlyModule())
.build();
}
return Realm.getInstance(mReadOnlyConfig);
}
import java.util.Date;
importio.realm.RealmObject;
public class ChildNotificationEntity extensions RealmObject {
private int childId;
private String message;
private String notifyAt;
public int getChildId(){
return childId;
}
public void setChildId(intchildId){
This.childId=childId;
}
public String getMessage() {
return message;
}
public void setMessage (String message) {
This.message=message;
}
public String getNotifyAt(){
return notifyAt;
}
public void setNotifyAt(String notifyAt){
this.notifyAt =notifyAt;
}
}
public static void importReadonlyRealmIfNeeded(Context context){
try{
// Intra-terminal Retention Version
SharedPreferences=context.getSharedPreferences (AppConst.PACKAGE_NAME, Context.MODE_PRIVATE);
intversionCode=s.getInt(KEY_VERSION_CODE, 0);
// Current build version
PackageInfo=context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
int currentVersionCode=pInfo.versionCode;
// Import runs when version code is updated
if(versionCode==currentVersionCode){
Log.i("realm", "import skip");
return;
}
Log.d(TAG, "Copy readonly.realm to this device");
copyBundledRealmFile(context.getResources().openRawResource(R.raw.readonly), READ_ONLY_FILE_NAME, context);
s.edit().putInt(KEY_VERSION_CODE, currentVersionCode).apply();
Log.i("realm", "success import");
} catch(PackageManager.NameNotFoundExceptione){
e.printStackTrace();
}
}
private static void copyBundledRealmFile(InputStream inputStream, String outFileName, Context context) {
try{
File file=new File(context.getFilesDir(), outFileName);
FileOutputStream outputStream=newFileOutputStream(file);
byte [ ] buf = new byte [1024];
int bytesRead;
while((bytesRead=inputStream.read(buf))>0){
outputStream.write(buf,0, bytesRead);
}
outputStream.close();
} catch(IOExceptione){
e.printStackTrace();
}
}
The migration does not appear to contain any instructions.
describes how notifyAt
is migrated from Date
to String
because there is an example of changing the type of field from String to int.
© 2024 OneMinuteCode. All rights reserved.