虽然我们通常会得到有利的评论,但以下错误正在堆积起来并让我们感到悲伤:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.svs.missions.MissionsGalleryView}: android.database.sqlite.SQLiteException: no such table: missions: , while compiling: SELECT * FROM missions WHERE banner is not null order by title COLLATE NOCASE
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2787)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
at android.app.ActivityThread.access$2300(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:144)
at android.app.ActivityThread.main(ActivityThread.java:4937)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteException: no such table: missions: , while compiling: SELECT * FROM missions WHERE banner is not null order by title COLLATE NOCASE
at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1409)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1293)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1248)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1328)
...
从assets文件夹复制db时,似乎并未创建所有表。以下是来自市场小组中用户的一条反馈消息:
“Whenever I click on "missions" the app force closes. all other links seem ok.”
所以真的很受欢迎。对于某些用户,似乎没有任何表被复制。
我很想完全删除数据库副本并在启动时创建数据库,但是我仍然不能保证将创建数据库(并且不会获得应用程序附带的任何元数据,除非我们在发布时下载它,大量数据btw)。虽然对我来说似乎有点傻。这么多不同的平台需要支持。如此脱节。
有趣的是我在每次启动时调用表创建代码只是为了确保db表存在,并且它没有修复它(这里的代码片段):
this.openDB();
db.execSQL("CREATE TABLE if not exists missions (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, description TEXT, created TEXT, orgHTML TEXT, UNIQUE(id) ON CONFLICT IGNORE);");
...
this.closeDB();
我发现了这个:
我已经应用了解决方法,但仍然收到错误报告。
我不确定它是否仅限于HTC设备,只是跟随上述论坛帖子的主角。
背景:
db位于assets文件夹中。它是2.8mb大,我分配.mp3扩展名以避免压缩,以便它复制(修复一个众所周知的旧问题)。
我尚未添加的一件事是检查可用空间,但接下来会是这样。如果我认为没有足够的可用空间,我可能只是创建整个数据库空。但是如果在复制资产文件夹db时它的可用空间不足,那么数据库应该被损坏我想。
BTW:Oncreate和Onupgrade目前是空的:
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
这适用于我们所有的测试设备:
HTC Aria,2.1,占地面积小,16mb堆
Original Droid,2.2.1
三星Galaxy,2.2
华硕平板电脑(没有型号),3.0Xoom,3.1
DB类扩展了sqliteopenhelper:
public class DBManager extends SQLiteOpenHelper {
以下是使用的代码(由于我们的用户都没有联系过我们,不幸的是我们不知道Log.e写的是什么):
...
private static final String DB_NAME = "db.mp3";
private static final String DB_PATH = "/data/data/com.svs/databases/";
...
public boolean createNewDatabaseFromAsset() {
File file = new File(DB_PATH , DB_NAME);
if (file.exists()) {
return true;
}
SQLiteDatabase db_Read = null;
db_Read=this.getReadableDatabase();
db_Read.close();
try {
InputStream assetsDB = this.context.getAssets().open(DB_NAME);
OutputStream dbOut = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
this.buildTables();
Log.i(TAG, "New database created...");
return true;
} catch (IOException e) {
Log.e(TAG, "IO Error. Could not create new database...");
e.printStackTrace();
this.buildTables();
return false;
} catch (SQLiteException e) {
Log.e(TAG, "Database Locked. Could not create new database...");
e.printStackTrace();
this.buildTables();
return false;
}
}
public DBManager openDB() {
if (!createNewDatabaseFromAsset())
return null;
if (db==null){
dbManager = new DBManager(context);
db = dbManager.getWritableDatabase();
}
return this;
}
答案 0 :(得分:2)
我想我会更新这个答案,因为它有点旧。 至少在平板电脑上,从Android API 19开始,您可以拥有多个用户。 Nexus 7上的帐户至少会进入目录/ data / users / 10 /
您现在必须执行以下操作:
InputStream input = this.context.getAssets().open(DATABASE_NAME);
File dbFile = context.getDatabasePath(DATABASE_NAME);
dbFile.getParentFile().mkdir();
dbFile.createNewFile();
OutputStream output = new FileOutputStream(dbFile.getAbsolutePath());
因此,您无法假设您的应用的路径静态位于/ data / data //数据库。
答案 1 :(得分:1)
对不起,留下了这个。
所以我最终决定检查并删除/创建第一次启动时复制的数据库中不存在的任何表(远程复制通常在包中提供的任何数据)。
这是一个我知道的黑客,但至少它已经过了我们无法解决的问题。
答案 2 :(得分:0)
看一下这篇文章here,它有一个很好的创建/复制db方法,它总是对我有用。还尝试将数据库切换成&lt; 1mb块然后重新组合 - 这就是我在处理大型数据库时所做的事情。 例如:
static private void CopyDatabase(Context Ctxt, File DBFile) throws IOException
{
AssetManager am = Ctxt.getAssets();
OutputStream os = new FileOutputStream(DBFile);
DBFile.createNewFile();
byte []b = new byte[1024];
int i, r;
String []Files = am.list("");
Arrays.sort(Files);
for(i=1;i<10;i++)
{
String fn = String.format("%d.db", i);
if(Arrays.binarySearch(Files, fn) < 0)
break;
InputStream is = am.open(fn);
while((r = is.read(b)) != -1)
os.write(b, 0, r);
is.close();
}
os.close();
}
希望这有帮助!