- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我创建了一个由表组成的 sqlite 数据库,数据库中填充了大约 2000 行。
我能够查询此表,并且当我通过模拟器执行此操作时一切正常。
但是当我在移动设备上测试它时,它会抛出以下错误:
android.database.sqlite.SQLiteException: no such table: person (code 1): , while compiling: SELECT name from person WHERE rowid = 292
当我在设备上尝试时,我希望我填充的 sqlite 数据库在我的设备上自动可用,但根据上述错误,情况似乎并非如此。
I did have a look through past issues and they do not match my issue.
I did not set my own path for the db storage location.
When I looked under Device File Explorer, the path for the database is /data/data/com.somepackage.myappname/databases/person
我已经尝试卸载该应用程序并再次重新安装,但没有任何区别。
我的 sdk 设置详细信息(如果相关)。
minSdkVersion 16
targetSdkVersion 27
Mobile device: Using Android version 8.0.0
请告知如何让数据库在安装时自动随应用程序一起提供(当我在 Android Studio 上单击运行时)。
这就是我将数据加载到数据库中的方式。这只运行了一次,我目前已经将这段代码注释掉了。
try {
SQLiteDatabase database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
database.execSQL("DROP TABLE IF EXISTS person");
database.execSQL("CREATE TABLE IF NOT EXISTS person (name VARCHAR, name_size INT(8))");
BufferedReader br = new BufferedReader(new InputStreamReader(getAssets().open("person.txt")));
String line;
while ((line = br.readLine()) != null) {
String sql = "INSERT INTO person (name, name_size) VALUES ('" + line + "', " + line.length() + ")";
database.execSQL(sql);
}database.close();
}
catch (Exception e){
e.printStackTrace();
}
我在 onCreate 方法下初始化数据库。
database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
单击按钮时,将执行以下方法。错误发生在该方法的第一行。
private String retrieveNextPerson(int randomIndex){
//error on this raw query
Cursor cursor = database.rawQuery("SELECT name from person WHERE rowid = " + randomIndex, null);
int wordIndex = cursor.getColumnIndex("name");
cursor.moveToFirst();
return cursor.getString(wordIndex);
}
最佳答案
假设您没有错误地认为在模拟器(或任何设备)上运行应用程序会更改包,以便分发将包含填充的数据库
分发预填充的数据库涉及
c) 从 Assets 文件夹中检索它。
SQLiteAssethelper
数据库文件需要存在于数据库文件夹中(您很可能需要创建它))。 然后我怀疑你过早地调用了:-
database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
这样做会创建没有人员表的人员数据库,从而导致您所描述的失败。
您需要在使用上述行之前加载数据。
或者,如果您在 database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
之后立即添加以下代码
Cursor csr = database.query("sqlite_master",null,"name='person'",null,null,null,null);
if (csr.getCount() < 1) {
database.execSQL("CREATE TABLE IF NOT EXISTS person (name VARCHAR, name_size INT(8))");
........ rest of the code that inserts data from the person.txt asset
}
表格将被创建。但是,它将是空的(您可以在此处复制 person.txt Assets 中的数据)
Thanks for reply. Not sure if you missed the part where I mentioned the database creation is already done and that part has been commented out. I invoked the db creation once and loaded it with data and the db is just sitting in the app now (at least for the emulator). The initialisation you mentioned should open an existing db with an existing table thus I don't see why that would be premature.
以下是对您的代码进行的非常可靠的修改,它将解决我认为最有可能出现的潜在问题:-
public class MainActivity extends AppCompatActivity {
public static final String DBNAME = "person";
public static final String TBNAME = "person";
public static final String COL_NAME = "name";
public static final String COL_NAME_SIZE = "name_size";
public static final String ASSET_FILENAME = "person.txt";
public static final String SQLITE_MASTER_TABLE = "sqlite_master";
public static final String COL_SQLITE_MATSER_NAME = "name";
static final int MIMINUM_ROWS_IN_PERSONTABLE = 1;
SQLiteDatabase db;
BufferedReader br;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPersonTable(); // Notes sets db either way
// FOR TESTING
long rows_in_person_table = DatabaseUtils.queryNumEntries(db,TBNAME);
Log.d(
"PERSON ROW COUNT",
"The number of rows in the " +
TBNAME +
" table is " +
String.valueOf(rows_in_person_table)
);
}
private void checkPersonTable() {
db = this.openOrCreateDatabase(DBNAME, Context.MODE_PRIVATE,null);
// Database will now exist but it may or may not contain the person table so check sqlite_master
Cursor csr = db.query(
SQLITE_MASTER_TABLE,
new String[]{COL_SQLITE_MATSER_NAME},
COL_SQLITE_MATSER_NAME + "=?",
new String[]{TBNAME},
null,null,null
);
// Cursor will contain 1 row if the person table exists so check count
int person_table_count = csr.getCount();
csr.close();
// Before attemtping to create the Person table ensure that the assets file exists
// If not then throw a RunTime exception
if (person_table_count < 1) {
try {
if (!Arrays.asList(getResources().getAssets().list("")).contains(ASSET_FILENAME)) {
StringBuilder sb = new StringBuilder();
throw new RuntimeException("Asset file " +
ASSET_FILENAME +
" not found in the assets folder." +
" The following assets were found" +
sb
);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (person_table_count < 1) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TBNAME +
"(" +
COL_NAME + " TEXT," +
COL_NAME_SIZE + " INTEGER" +
")"
);
loadPersonsFromAssets();
} else {
// <<<<<<<<<< NOTE Optional will load data from assets if miminum nuber of rows
// aren't in the person table
if (DatabaseUtils.queryNumEntries(db,TBNAME) < MIMINUM_ROWS_IN_PERSONTABLE) {
loadPersonsFromAssets();
}
}
}
// Load the person table from the Assets File
private void loadPersonsFromAssets() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(getAssets().open(ASSET_FILENAME)));
String line, sql;
int lines_read = 0;
db.beginTransaction();
while ((line = br.readLine()) != null) {
sql = "INSERT INTO " + TBNAME + " VALUES('" + line + "'," + String.valueOf(line.length()) + ")";
db.execSQL(sql);
lines_read++;
}
db.setTransactionSuccessful();
db.endTransaction();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Asset File " + ASSET_FILENAME + " not found in the assets folder.");
}
}
}
这将:-
如果 Assets 文件 person.txt 不存在,那么您将得到类似于以下的异常:-
06-10 03:58:43.503 3097-3097/personthing.so50777840 E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{personthing.so50777840/personthing.so50777840.MainActivity}: java.lang.RuntimeException: Asset file person.txt not found in the assets folder. The following assets were found
found asset file :- images
found asset file :- notperson.txt
found asset file :- sounds
found asset file :- webkit
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Asset file person.txt not found in the assets folder. The following assets were found
found asset file :- images
found asset file :- notperson.txt
found asset file :- sounds
found asset file :- webkit
at personthing.so50777840.MainActivity.checkPersonTable(MainActivity.java:83)
at personthing.so50777840.MainActivity.onCreate(MainActivity.java:39)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
... 11 more
请注意,在此阶段数据库将存在(由于 openOrCreateDatabase
)并且它将包含两个表(sqlite_master 和 android_metadata)但不包含 person 表,例如:-
但是,创建正确的 Assets 文件 person.txt(将 notperson.txt 重命名为 person.text)将导致创建表并加载数据:-
例如如果 person.txt 是:-
然后运行该应用程序将导致日志包含:-
06-10 04:39:04.277 3325-3325/? D/PERSON ROW COUNT: The number of rows in the person table is 11
关于java - 在移动设备上找不到 sqlite db,但可以在模拟器上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50777840/
例如,我有一个父类Author: class Author { String name static hasMany = [ fiction: Book,
代码如下: dojo.query(subNav.navClass).forEach(function(node, index, arr){ if(dojo.style(node, 'd
我有一个带有 Id 和姓名的学生表和一个带有 Id 和 friend Id 的 Friends 表。我想加入这两个表并找到学生的 friend 。 例如,Ashley 的 friend 是 Saman
我通过互联网浏览,但仍未找到问题的答案。应该很容易: class Parent { String name Child child } 当我有一个 child 对象时,如何获得它的 paren
我正在尝试创建一个以 Firebase 作为我的后端的社交应用。现在我正面临如何(在哪里?)找到 friend 功能的问题。 我有每个用户的邮件地址。 我可以访问用户的电话也预订。 在传统的后端中,我
我主要想澄清以下几点: 1。有人告诉我,在 iOS 5 及以下版本中,如果您使用 Game Center 设置多人游戏,则“查找 Facebook 好友”(如与好友争夺战)的功能不是内置的,因此您需要
关于redis docker镜像ENTRYPOINT脚本 docker-entrypoint.sh : #!/bin/sh set -e # first arg is `-f` or `--some-
我是一名优秀的程序员,十分优秀!