android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(代码14):无法打开数据库仍然无法解决问题

Moe*_*hry 0 android android-logcat android-studio android-database

人们已经问过这个问题,但经过许多人的步骤后,我仍然无法解决问题,请帮助。\ni还在清单文件中添加了权限

\n\n
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>\n<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是 logcat 错误。

\n\n
07-17 15:23:58.253 14526-14526/com.techmobile2.yogahome E/AndroidRuntime: FATAL EXCEPTION: main\nProcess: com.techmobile2.yogahome, PID: 14526\njava.lang.RuntimeException: Unable to start activity ComponentInfo{com.techmobile2.yogahome/com.techmobile2.yogahome.SettingPage}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database\n    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)\n    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2480)\n    at android.app.ActivityThread.access$800(ActivityThread.java:151)\n    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377)\n    at android.os.Handler.dispatchMessage(Handler.java:102)\n    at android.os.Looper.loop(Looper.java:155)\n    at android.app.ActivityThread.main(ActivityThread.java:5725)\n    at java.lang.reflect.Method.invoke(Native Method)\n    at java.lang.reflect.Method.invoke(Method.java:372)\n    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1030)\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:825)\n Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database\n    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)\n    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:235)\n    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:219)\n    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:468)\n    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:190)\n    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:182)\n    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:874)\n    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:854)\n    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:752)\n    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:727)\n    at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getReadableDatabase(SQLiteAssetHelper.java:264)\n    at com.techmobile2.yogahome.Database.YogaDB.getSettingMode**(YogaDB.java:21)**\n    at com.techmobile2.yogahome.SettingPage.onCreate**(SettingPage.java:41)**\n    at android.app.Activity.performCreate(Activity.java:6018)\n    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)\n    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370)\n    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2480)\xc2\xa0\n    at android.app.ActivityThread.access$800(ActivityThread.java:151)\xc2\xa0\n    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377)\xc2\xa0\n    at android.os.Handler.dispatchMessage(Handler.java:102)\xc2\xa0\n    at android.os.Looper.loop(Looper.java:155)\xc2\xa0\n    at android.app.ActivityThread.main(ActivityThread.java:5725)\xc2\xa0\n    at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n    at java.lang.reflect.Method.invoke(Method.java:372)\xc2\xa0\n    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1030)\xc2\xa0\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:825)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是yogaDB.java 文件,我也会提到行号

\n\n
public class YogaDB extends SQLiteAssetHelper {\n\nprivate static final String DB_NAME = "yoga.db";\nprivate static final int DB_VER=1;\n\npublic YogaDB(Context context) {\n    super(context, DB_NAME, null, DB_VER);\n}\n\npublic int getSettingMode()\n{\n    **SQLiteDatabase db = getReadableDatabase();** //THIS is line 21\n    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();\n\n    String[] sqlSelect = {"Mode"};\n    String sqlTable = "Setting";\n\n    qb.setTables(sqlTable);\n    Cursor c = qb.query(db,sqlSelect,null,null,null,null,null);\n    c.moveToFirst();\n    return c.getInt(c.getColumnIndex("Mode"));\n}\n\npublic void saveSettingMode(int value)\n{\n    SQLiteDatabase db = getReadableDatabase();\n    String query = "UPDATE Setting SET Mode = "+value;\n    db.execSQL(query);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是SettingPage.java,我还将提到行号

\n\n
public class SettingPage extends AppCompatActivity {\n\nButton btnSave;\nRadioButton rdiEasy,rdiMedium,rdiHard;\nRadioGroup rdiGroup;\nYogaDB yogaDB;\nToggleButton switchAlarm;\nTimePicker timePicker;\n\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_setting_page);\n\n    //Init view\n    btnSave = (Button)findViewById(R.id.btnSave);\n    rdiGroup = (RadioGroup)findViewById(R.id.rdiGroup);\n    rdiEasy = (RadioButton)findViewById(R.id.rdiEasy);\n    rdiMedium = (RadioButton)findViewById(R.id.rdiMedium);\n    rdiHard = (RadioButton)findViewById(R.id.rdiHard);\n\n    switchAlarm = (ToggleButton)findViewById(R.id.switchAlarm);\n\n    timePicker = (TimePicker)findViewById(R.id.timePicker);\n\n    yogaDB = new YogaDB(this);\n\n    int mode = yogaDB.getSettingMode(); this is line 41\n    setRadioButton(mode);\n\n    //Event\n    btnSave.setOnClickListener(new View.OnClickListener() {\n        @Override\n        public void onClick(View v) {\n            saveWorkoutMode();\n        }\n    });\n\n}\n\nprivate void saveWorkoutMode() {\n    int selectedID = rdiGroup.getCheckedRadioButtonId();\n    if(selectedID == rdiEasy.getId())\n        yogaDB.saveSettingMode(0);\n    else if(selectedID == rdiMedium.getId())\n        yogaDB.saveSettingMode(1);\n    else if(selectedID == rdiHard.getId())\n        yogaDB.saveSettingMode(2);\n}\n\nprivate void setRadioButton(int mode) {\n    if(mode == 0)\n        rdiGroup.check(R.id.rdiEasy);\n    else if(mode == 1)\n        rdiGroup.check(R.id.rdiMedium);\n    else if(mode == 2)\n        rdiGroup.check(R.id.rdiHard);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 sql 数据库文件名为yoga.db\n请帮助我解决我的问题

\n

Ume*_*han 6

问题:大多数情况下,当您从多个线程访问 SQLite 数据库时,会发生SQLiteCantOpenDatabaseException 。假设您已在一个线程中打开数据库,并尝试在另一个线程中访问数据库将导致SQLiteCantOpenDatabaseException异常。

解决方案:创建 SQLiteOpenHelper 类的单例对象,并始终对多个线程使用相同的实例。

样本:

DBHelper类:

public class DBHelper extends SQLiteOpenHelper {
  private DBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }

  public synchronized static DBHelper getInstance(Context context) {
    if (dbHelper == null) {
        dbHelper = new DBHelper(context);
    }

    return dbHelper;
  }

  @Override
  public void onCreate(SQLiteDatabase sqLiteDatabase) {
    //...
  }

  @Override
  public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    //...
    onCreate(sqLiteDatabase);
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

private static SQLiteDatabase database;


DBHelper dbHelper = DBHelper.getInstance(context);
if (database == null) {
  database = dbHelper.getWritableDatabase();
}
Run Code Online (Sandbox Code Playgroud)

注意:永远不要自己关闭 SqliteDatabase 实例,android 系统会为你做这件事。