Android SQLiteOpenHelper错误 - 调用super必须是构造函数中的第一个语句

时间:2016-05-10 07:06:13

标签: android constructor android-sqlite super sqliteopenhelper

首先我要说的是,在提出这个问题之前,我已经阅读了很多类似的问题,但我无法找到解决问题的方法。

我正在尝试扩展SQLiteOpenHelper类,但有两个显着差异 -

  1. 我正在使用SQLCipher(如果我使用super,使用它并不会烦恼 构造函数中的顶部)
  2. 从中获取我的数据库位置 SharedPreferences (这就是为什么,我必须把它放在超级之前)
  3. 例如,以下构造函数工作正常(我已经排除了与我的问题无关的导入和函数) -

    import net.sqlcipher.Cursor;
    import net.sqlcipher.SQLException;
    import net.sqlcipher.database.SQLiteDatabase;
    import net.sqlcipher.database.SQLiteOpenHelper;
    
    public class LocalDBHelper extends SQLiteOpenHelper {
        public static String DB_LOCAL_NAME = "localdata.db";
        public static SQLiteDatabase myDataBase;
        private final Context myContext;
    
        public LocalDBHelper(Context context) {
            super(context, Environment.getExternalStorageDirectory().toString()+File.separator + "myFolder"
                    + "/" + DB_LOCAL_NAME, null, 1);
            this.myContext = context;
            SQLiteDatabase.loadLibs(context);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
    
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int i, int i1) {
            onCreate(db);
        }
    }
    

    但是,在我的情况下,我想允许数据库位置变量(例如,用户可以从Downloads文件夹中使用它,或者如果用户不允许使用外部存储(如果是Android 6.0),然后使用内部存储或根据情况使用getExternalFilesDir() - >所以,简而言之,我在共享首选项中保存数据库位置,并尝试通过修改构造函数来使用它 -

    public QuestionBankDBHelper(Context context) {
            SharedPreferences getPrefs = PreferenceManager
                    .getDefaultSharedPreferences(NoContextAvailable); //What should I use here for the context ?
            String getDBLocation = getPrefs.getString("MY_DATABASE_LOCATION", Environment.getExternalStorageDirectory().toString()+File.separator + "myFolder"
                    + "/" + DB_LOCAL_NAME);
            super(context, getDBLocation, null, 1);
            this.myContext = context;
            SQLiteDatabase.loadLibs(context);
        }
    

    显然上面修改的构造函数不起作用,并给出以下两个错误 -

    1. getDefaultSharedPreferences可以使用哪种上下文?
    2. 调用super必须是Constructor中的第一个语句。
    3. 即使经过大量的试验和搜索,我也无法解决如何解决这两个问题,并将我的数据库位置变为可变。

2 个答案:

答案 0 :(得分:3)

getDBLocation代码移动到静态方法中:

private static String getDBLocation(Context context) {
    SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    String getDBLocation = getPrefs.getString("MY_DATABASE_LOCATION", 
            Environment.getExternalStorageDirectory().toString() 
                + File.separator + "myFolder" + "/" + DB_LOCAL_NAME);
    return getDBLocation;
}

public QuestionBankDBHelper(Context context) {
    super(context, getDBLocation(context), null, 1);
    this.myContext = context;
    SQLiteDatabase.loadLibs(context);
}

答案 1 :(得分:2)

简单回答:

  1. 创建接受上下文作为参数并返回DB路径的静态函数
  2. super作为第一个语句,并使用static function return作为路径参数
  3. 正确的解决方案是删除有关在此课程中查找数据库路径的任何知识。在构造此类之前,您应该执行所有检查,计算,问题,并且只调用具有已定义路径的此类的构造函数