使用 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
}