注意:
1.public Cursor rawQuery(String sql, String[] selectionArgs)
Cursor游标是查询后返回的结果集合,游标的意思是指向集合中的某行。
该函数返回的cursor游标的初始位置是在-1,即在第一组数据之前,此时不可获取数据,否则会报错:CursorIndexOutOfBoundsException: Index -1 requested。在调用Cursor.moveToFirst()后,游标位置为0,此时可以取数据。
如果返回结果包含0条,游标初始位置为-1,moveToFirst()后,游标位置为0,但此时取数据仍然会出错。所以在取是数据之前最好判断结果不为空。
2.SQL语句中字母大小写均可(竟然可以混搭!),但是要注意空格不能少。
3.数据库创建后默认存放地址和默认数据库读取地址是:/data/data/your_app_paket_name/databases
4.数据库从raw中拷贝到默认数据库地址,出现错误,只拷贝3KB。
要使用编辑好的数据库,需要将数据库放在raw中,拷贝到默认的文件夹,而经常出现的错误是,只拷贝了3KB!!
我们的代码经常是这样:
try { if(!(new File(DBPath+"/"+DBName).exists())){ InputStream is = this.getResources().openRawResource(R.raw.schoolinfor); FileOutputStream fos = new FileOutputStream(DBPath+"/"+DBName); byte[] buffer = new byte[500]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.flush(); fos.close(); is.close(); } } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }
这里有个错误,DBPath是"/data/data/paket_name/databases",而路径/dabases是在没有使用数据库相关API时是不存在的。在复制操作中缺少对路径/dabases的判断,会有两个可能的错误方向:
1.在这个复制操作之前,有用过数据库API,生产了一个空的数据库,其中只有android_metadata这个表,大小在3KB,这样在if语句中就不会去走复制操作的分支,而呈现给你的结果是,你只复制了3KB!而隐藏在背后的事实是:少年,这是一个错觉,你一点都没有复制!
2./dabases确实不存在,导致在FileOutputStream fos = new FileOutputStream(DBPath+"/"+DBName);操作中因为路径不存在,抛出异常,复制失败。
下面是修正后的代码,跑起来畅通无阻:
try { if(!new File(DBPath).exists()) new File(DBPath).mkdirs(); if(!(new File(DBPath+"/"+DBName).exists())){ InputStream is = this.getResources().openRawResource(R.raw.schoolinfor); FileOutputStream fos = new FileOutputStream(DBPath+"/"+DBName); byte[] buffer = new byte[500]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.flush(); fos.close(); is.close(); } } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }