SQLiteCantOpenDatabaseException:未知错误(代码 14):无法打开数据库(仅在对应用程序进行单元测试时)
Posted
技术标签:
【中文标题】SQLiteCantOpenDatabaseException:未知错误(代码 14):无法打开数据库(仅在对应用程序进行单元测试时)【英文标题】:SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database (Only when unit testing the app) 【发布时间】:2017-10-18 14:14:45 【问题描述】:所以我最近在我的应用程序中添加了持久性,我得到了这个错误,但有趣的部分是应用程序运行良好,即使持久对象检索它们和所有内容,但是在运行单元测试时,我得到上面写的错误。
这是我的应用程序中有趣的部分
清单权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission." />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
这里是 gradle config 默认配置块
compileSdkVersion 24
buildToolsVersion '25.0.0'
defaultConfig
applicationId "mehungry.com.myapplicationnavigationdawerdemo"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
minSdkVersion 22
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled = true
jackOptions
enabled true
我的数据库助手:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper
public static final int DATABASE_VERSION = 2;
public static final String DATABASE_NAME = "MeHungryApp.db";
private SQLiteDatabase database;
private final Context context;
public DatabaseHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL(CreateStatments.ATABLE);
db.execSQL(CreateStatments.BTABLE);
db.execSQL(CreateStatments.CTABLE);
db.execSQL(CreateStatments.DTABLE);
db.execSQL(CreateStatments.ETABLE);
db.execSQL(CreateStatments.FTABLE);
db.execSQL(CreateStatments.GTABLE);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
Log.w(DatabaseHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + ATableDef.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + BTableDef.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + CTableDef.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + DTableDef.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + ETableDef.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + FTableDef.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + GTableDef.TABLE_NAME);
onCreate(db);
我的数据库测试类(暂时什么都不做)
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MealEntityPersistenceTest
private SQLiteDatabase database;
private DatabaseHelper databaseHelper;
public MealEntityPersistenceTest()
@Before
public void setUp()
databaseHelper = new
DatabaseHelper(InstrumentationRegistry.getContext());
database = databaseHelper.getWritableDatabase();
@Test
public void testInsertRecipe()
这是我在 Android Monitor 中看到的内容
05-18 18:16:12.437 12672-12672/? I/MonitoringInstrumentation: Activities that are still in CREATED to STOPPED: 0
05-18 18:16:12.438 12672-12695/? E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
05-18 18:16:12.439 12672-12695/? E/SQLiteLog: (14) os_unix.c:30046: (2) open(/data/data/mehungry.com.myapplicationnavigationdawerdemo.test/databases/MeHungryApp.db) -
05-18 18:16:12.441 12672-12695/? E/SQLiteDatabase: Failed to open database '/data/data/mehungry.com.myapplicationnavigationdawerdemo.test/databases/MeHungryApp.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:218)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:202)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1181)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at mehungry.MealEntityPersistenceTest.setUp(MealEntityPersistenceTest.java:37)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)
05-18 18:16:12.442 12672-12695/? I/TestRunner: failed: testInsertRecipe(mehungry.MealEntityPersistenceTest)
05-18 18:16:12.442 12672-12695/? I/TestRunner: ----- begin exception -----
05-18 18:16:12.443 12672-12695/? I/TestRunner: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:218)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:202)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1181)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at mehungry.MealEntityPersistenceTest.setUp(MealEntityPersistenceTest.java:37)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)
05-18 18:16:12.443 12672-12695/? I/TestRunner: ----- end exception -----
我越来越绝望,因为我已经看到了大量类似的问题,但没有任何帮助我,所以任何类型的方向或疯狂的猜测都将不胜感激。
【问题讨论】:
【参考方案1】:所以经过一番调查,我发现问题出在数据库路径上
测试时:
/data/data/mehungry.com.myapplicationnavigationdawerdemo.test/databases/MeHungryApp.db
运行整个应用程序时:
/data/data/mehungry.com.myapplicationnavigationdawerdemo/databases/MeHungryApp.db
这是问题所在,这种不一致已为我解决 当我确实更改了我的 DatabaseHelper 构造函数调用时
从此:
databaseHelper = new DatabaseHelper(InstrumentationRegistry.getContext());
到这个:
databaseHelper = new DatabaseHelper(InstrumentationRegistry.getTargetContext());
希望它可以在某个时候对某人有所帮助。
【讨论】:
非常感谢!从在线文档和示例来看,getContext() 似乎是其中一个,但 getTargetContext() 也为我解决了这个问题。 谢谢!这个问题花了我几个小时……有人应该用这些信息更新谷歌文档。 感谢您的回答,我猜现在这个问题/答案在 google 搜索结果中也上升了,非常有用,很犀利!以上是关于SQLiteCantOpenDatabaseException:未知错误(代码 14):无法打开数据库(仅在对应用程序进行单元测试时)的主要内容,如果未能解决你的问题,请参考以下文章