使用 ActiveAndriod ORM 时插入 Id=null 时出错
Error inserting Id=null when using ActiveAndriod ORM
感谢您抽出宝贵的时间。
我正在为我的 android project.I 创建的应用程序 class 使用 ActiveAndroid ORM,我在其中初始化 ActiveAndroid.I 还创建了扩展模型的 POJO class ActiveAndroid.
在应用程序标签内的 Manifiest 中,我使用元作为
<meta-data
android:name="AA_DB_NAME"
android:value="myFhn.db" />
<meta-data
android:name="AA_DB_VERSION"
android:value="3" />
但是在保存对象时我无法保存它。我不知道自己在做什么,有时会节省,有时不会。
当我调用这个 clearApplicationData 方法时,我遇到了上述问题。
public static void clearApplicationData(final Context context) {
File cache = context.getCacheDir();
File appDir = new File(cache.getParent());
if (appDir.exists()) {
String[] children = appDir.list();
for (String s : children) {
File f = new File(appDir, s);
if (deleteDir(f)) {
AppLog.i("Util", String.format("DELETED::", f.getAbsolutePath()));
}
}
}
context.getSharedPreferences(context.getPackageName(), context.MODE_PRIVATE).edit().clear();
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
AppLog.i("Util", "DELETING:: " + aChildren);
boolean success = deleteDir(new File(dir, aChildren));
if (!success) {
return false;
}
}
}
assert dir != null;
return dir.delete();
}
public static void restartApplication(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int pendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, pendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
android.os.Process.killProcess(android.os.Process.myPid());
}
这是我的应用程序class
public class FHNapplication extends com.activeandroid.app.Application {
public static final String TAG = FHNapplication.class.getSimpleName();
private static FHNapplication mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
try {
ActiveAndroid.initialize(this);
Log.i(TAG,"initialized");
} catch (Exception e) {
e.printStackTrace();
}
MultiDex.install(getBaseContext());
Fabric.with(this, new Crashlytics());
}
public static synchronized FHNapplication getInstance() {
return mInstance;
}
@Override
public void onTerminate() {
super.onTerminate();
ActiveAndroid.dispose();
}
}
这是我的登录 POJO class
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Table(name = "User")
public class LoginData extends Model {
@Column(name = "access_token")
@JsonProperty("accessToken")
private String accessToken;
@Column(name = "full_name")
@JsonProperty("fullname")
private String fullname;
@Column(name = "fhn_id")
@JsonProperty("fhnId")
private String fhnId;
@Column(name = "imageUrl")
@JsonProperty("image")
private String imageUrl;
public LoginData() {
super();
}
public static LoginData getUserData() {
return new Select().from(LoginData.class).executeSingle();
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getFhnId() {
return fhnId;
}
public void setFhnId(String fhnId) {
this.fhnId = fhnId;
}
}
这就是我试图保存对象的方式
LoginData loginData = event.getLoginResponse().getData();
loginData.save();
登录时出现此错误
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : / rc : 0 st_mode : 40755 st_uid : 0 st_gid : 0 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/ rc : 0 st_mode : 40771 st_uid : 1000 st_gid : 1000 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/ rc : 0 st_mode : 40771 st_uid : 1000 st_gid : 1000 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/com.bidhee.familyhealthnepal/ rc : 0 st_mode : 40751 st_uid : 10260 st_gid : 10260 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/com.bidhee.familyhealthnepal/databases/ rc : -1 st_mode : 0 st_uid : 0 st_gid : 0 Type:file
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/com.bidhee.familyhealthnepal/databases/myFhn.db rc : -1 st_mode : 0 st_uid : 0 st_gid : 0 Type:file
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1802) os_unix.c:32353: (2) stat(/data/data/com.bidhee.familyhealthnepal/databases/myFhn.db) -
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1802) statement aborts at 29: [INSERT INTO User(Id,fhn_id,imageUrl,access_token,full_name) VALUES (?,?,?,?,?)]
03-18 14:10:01.813 16981-16981/com.bidhee.familyhealthnepal E/SQLiteDatabase: Error inserting Id=null fhn_id=FHN-2015-3306 imageUrl=http://familyhealthnepal.com/uploads/members/images (3).jpg access_token=XHy4rHWR07ZivAZSeL5HLYWd full_name=Santosh Kumar Poudel
android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 1802)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:972)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1603)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1473)
at com.activeandroid.Model.save(Model.java:155)
at com.bidhee.familyhealthnepal.activity.LoginActivity.LoginResultEvent(LoginActivity.java:318)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.squareup.otto.EventHandler.handleEvent(EventHandler.java:89)
at com.squareup.otto.Bus.dispatch(Bus.java:385)
at com.squareup.otto.Bus.dispatchQueuedEvents(Bus.java:368)
at com.squareup.otto.Bus.post(Bus.java:337)
at com.bidhee.familyhealthnepal.bus.EventBus.post(EventBus.java:44)
at com.bidhee.familyhealthnepal.controller.LoginPostTask.onResponse(LoginPostTask.java:32)
at retrofit.ExecutorCallAdapterFactory$ExecutorCallback.run(ExecutorCallAdapterFactory.java:86)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
调用 clearApplicationData(...)
方法会从您的应用程序安装文件夹中删除数据库文件,因此稍后您会尝试 save/insert 一个不存在的数据库中的记录,并且您会看到错误在你的 logcat 中。
因此,要么在调用 clearApplicationData(...)
时不要删除 myFhn.db
文件,要么在 clearApplicationData(...)
完成后立即重新创建数据库。
编辑:
例如,您可以通过将 deleteDir(File dir)
方法更改为:
来排除您的数据库文件被删除
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
AppLog.i("Util", "DELETING:: " + aChildren);
if(!"myFhn.db".equals(aChildren.getName()) {
boolean success = deleteDir(new File(dir, aChildren));
if (!success) {
return false;
}
}
}
}
assert dir != null;
return true; //dir.delete(); ->cannot delete dir since it contains the database file
}
感谢您抽出宝贵的时间。
我正在为我的 android project.I 创建的应用程序 class 使用 ActiveAndroid ORM,我在其中初始化 ActiveAndroid.I 还创建了扩展模型的 POJO class ActiveAndroid.
在应用程序标签内的 Manifiest 中,我使用元作为
<meta-data
android:name="AA_DB_NAME"
android:value="myFhn.db" />
<meta-data
android:name="AA_DB_VERSION"
android:value="3" />
但是在保存对象时我无法保存它。我不知道自己在做什么,有时会节省,有时不会。
当我调用这个 clearApplicationData 方法时,我遇到了上述问题。
public static void clearApplicationData(final Context context) {
File cache = context.getCacheDir();
File appDir = new File(cache.getParent());
if (appDir.exists()) {
String[] children = appDir.list();
for (String s : children) {
File f = new File(appDir, s);
if (deleteDir(f)) {
AppLog.i("Util", String.format("DELETED::", f.getAbsolutePath()));
}
}
}
context.getSharedPreferences(context.getPackageName(), context.MODE_PRIVATE).edit().clear();
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
AppLog.i("Util", "DELETING:: " + aChildren);
boolean success = deleteDir(new File(dir, aChildren));
if (!success) {
return false;
}
}
}
assert dir != null;
return dir.delete();
}
public static void restartApplication(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int pendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, pendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
android.os.Process.killProcess(android.os.Process.myPid());
}
这是我的应用程序class
public class FHNapplication extends com.activeandroid.app.Application {
public static final String TAG = FHNapplication.class.getSimpleName();
private static FHNapplication mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
try {
ActiveAndroid.initialize(this);
Log.i(TAG,"initialized");
} catch (Exception e) {
e.printStackTrace();
}
MultiDex.install(getBaseContext());
Fabric.with(this, new Crashlytics());
}
public static synchronized FHNapplication getInstance() {
return mInstance;
}
@Override
public void onTerminate() {
super.onTerminate();
ActiveAndroid.dispose();
}
}
这是我的登录 POJO class
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Table(name = "User")
public class LoginData extends Model {
@Column(name = "access_token")
@JsonProperty("accessToken")
private String accessToken;
@Column(name = "full_name")
@JsonProperty("fullname")
private String fullname;
@Column(name = "fhn_id")
@JsonProperty("fhnId")
private String fhnId;
@Column(name = "imageUrl")
@JsonProperty("image")
private String imageUrl;
public LoginData() {
super();
}
public static LoginData getUserData() {
return new Select().from(LoginData.class).executeSingle();
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getFhnId() {
return fhnId;
}
public void setFhnId(String fhnId) {
this.fhnId = fhnId;
}
}
这就是我试图保存对象的方式
LoginData loginData = event.getLoginResponse().getData();
loginData.save();
登录时出现此错误
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : / rc : 0 st_mode : 40755 st_uid : 0 st_gid : 0 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/ rc : 0 st_mode : 40771 st_uid : 1000 st_gid : 1000 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/ rc : 0 st_mode : 40771 st_uid : 1000 st_gid : 1000 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/com.bidhee.familyhealthnepal/ rc : 0 st_mode : 40751 st_uid : 10260 st_gid : 10260 Type:dir
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/com.bidhee.familyhealthnepal/databases/ rc : -1 st_mode : 0 st_uid : 0 st_gid : 0 Type:file
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1) Path : /data/data/com.bidhee.familyhealthnepal/databases/myFhn.db rc : -1 st_mode : 0 st_uid : 0 st_gid : 0 Type:file
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1802) os_unix.c:32353: (2) stat(/data/data/com.bidhee.familyhealthnepal/databases/myFhn.db) -
03-18 14:10:01.793 16981-16981/com.bidhee.familyhealthnepal E/SQLiteLog: (1802) statement aborts at 29: [INSERT INTO User(Id,fhn_id,imageUrl,access_token,full_name) VALUES (?,?,?,?,?)]
03-18 14:10:01.813 16981-16981/com.bidhee.familyhealthnepal E/SQLiteDatabase: Error inserting Id=null fhn_id=FHN-2015-3306 imageUrl=http://familyhealthnepal.com/uploads/members/images (3).jpg access_token=XHy4rHWR07ZivAZSeL5HLYWd full_name=Santosh Kumar Poudel
android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 1802)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:972)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1603)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1473)
at com.activeandroid.Model.save(Model.java:155)
at com.bidhee.familyhealthnepal.activity.LoginActivity.LoginResultEvent(LoginActivity.java:318)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.squareup.otto.EventHandler.handleEvent(EventHandler.java:89)
at com.squareup.otto.Bus.dispatch(Bus.java:385)
at com.squareup.otto.Bus.dispatchQueuedEvents(Bus.java:368)
at com.squareup.otto.Bus.post(Bus.java:337)
at com.bidhee.familyhealthnepal.bus.EventBus.post(EventBus.java:44)
at com.bidhee.familyhealthnepal.controller.LoginPostTask.onResponse(LoginPostTask.java:32)
at retrofit.ExecutorCallAdapterFactory$ExecutorCallback.run(ExecutorCallAdapterFactory.java:86)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
调用 clearApplicationData(...)
方法会从您的应用程序安装文件夹中删除数据库文件,因此稍后您会尝试 save/insert 一个不存在的数据库中的记录,并且您会看到错误在你的 logcat 中。
因此,要么在调用 clearApplicationData(...)
时不要删除 myFhn.db
文件,要么在 clearApplicationData(...)
完成后立即重新创建数据库。
编辑:
例如,您可以通过将 deleteDir(File dir)
方法更改为:
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
AppLog.i("Util", "DELETING:: " + aChildren);
if(!"myFhn.db".equals(aChildren.getName()) {
boolean success = deleteDir(new File(dir, aChildren));
if (!success) {
return false;
}
}
}
}
assert dir != null;
return true; //dir.delete(); ->cannot delete dir since it contains the database file
}