由sqlite在手机上的存储位置,引发的onCreate在哪里执行的总结

前端之家收集整理的这篇文章主要介绍了由sqlite在手机上的存储位置,引发的onCreate在哪里执行的总结前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载请注明出处,谢谢: http://www.jb51.cc/article/p-xwhhaoli-bgq.html

我们都知道,android为了操作数据库,一般是继承sqliteOpenHelper类,并实现他的三个函数

如下所示:

  1. package jz.his.db;
  2.  
  3. import android.content.Context;
  4. import android.database.sqlite.sqliteDatabase;
  5. import android.database.sqlite.sqliteDatabase.CursorFactory;
  6. import android.database.sqlite.sqliteOpenHelper;
  7.  
  8. public class MessageDataBase extends sqliteOpenHelper {
  9.  
  10. public MessageDataBase(Context context,String name,CursorFactory factory,int version) {
  11. super(context,name,factory,version);
  12. }
  13.  
  14. @Override
  15. public void onCreate(sqliteDatabase db) {
  16. db.execsql("create table lgx_table(_id integer primary key autoincrement," +
  17. "name varchar(20),content varchar(40),time varchar(20),head varchar(20),isCheck byte)");
  18. }
  19.  
  20. @Override
  21. public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {
  22. }
  23.  
  24. }
  1. </pre><p>可以看到创建了一个名为lgx_table的表,里面有一id,content等列。</p><p></p>然后在Activity里,通过getWritableDatabase或者getReadableDatabase()方法来实例化一个sqliteDatabase<p></p><p></p><pre name="code" class="java">MessageDataBase messageDataBase = new MessageDataBase(context,"lgx",null,1);
  2. sqliteDatabase database = messageDataBase.getWritableDatabase();


我们可以看到,创建了一个名字为“lgx”的数据库


这里提出一个问题,通过以上的步骤后,数据库保存在哪里了呢?


数据库保存在data/data/[your packageName]/databses,

1.如果是模拟器,直接通过Eclipse下,通过这样的步骤去看 DBMS--->File Explorer-->data---->data--->your packageName


  1.  

网上很多介绍,我这里不介绍。

2.如果是真机,首先这个真机是root过了,下载一个Root Explorer。我的测试机是华为荣耀3c。

当我们执行完了以上的步骤后,进入data/data/jz.his.jzhis/databases/会看到这样的情景。

其实lgx就是我们刚刚创建的数据库,lgx-journal是数据库日志。

现在我们知道了,数据库存储的位置了,你以为这就是我写这篇博客的目的?继续往下看吧,嘿嘿。

如果我不想再手机系统内存中保存数据库,而是想将我的数据库放在手机sd卡中,那应该怎么做呢。

首先,我在res/raw中放一个现成的数据库,待会在代码里,将它拷入手机sd卡中。

看下面的代码

  1. package com.example.province;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.ArrayList;
  8.  
  9. import android.content.Context;
  10. import android.database.Cursor;
  11. import android.database.sqlite.sqliteDatabase;
  12. import android.database.sqlite.sqliteDatabase.CursorFactory;
  13. import android.database.sqlite.sqliteException;
  14. import android.database.sqlite.sqliteOpenHelper;
  15. import android.os.Environment;
  16.  
  17. public class CopyOfCityInfoDataSupport2 {
  18. private static CopyOfCityInfoDataSupport2 cityInfoDataSupport;
  19. /**
  20. * 数据库在手机里的路径
  21. */
  22. private static String DATABASE_PATH = Environment
  23. .getExternalStorageDirectory() + "/aaaaa/";
  24. /**
  25. * 数据库名称
  26. */
  27. public static final String dbName = "mzk_db";
  28. private sqliteDatabase mSDB;
  29.  
  30. public static CopyOfCityInfoDataSupport2 getInstance(Context context) {
  31. initDataBase(context);
  32. if (cityInfoDataSupport == null) {
  33. cityInfoDataSupport = new CopyOfCityInfoDataSupport2();
  34. }
  35. return cityInfoDataSupport;
  36.  
  37. }
  38.  
  39. /**
  40. * 初试化数据库
  41. */
  42. private static void initDataBase(Context context) {
  43. boolean dbExist = checkDataBase();
  44. if (dbExist) {
  45.  
  46. } else {
  47. // 如果不存在,则将raw里的数据存入手机sd卡
  48. copyDataBase(context);
  49. }
  50. }
  51.  
  52. /**
  53. * 复制数据库到手机指定文件夹下
  54. *
  55. * @throws IOException
  56. */
  57. private static void copyDataBase(Context context) {
  58. String databaseFilenames = DATABASE_PATH + dbName;
  59. File dir = new File(DATABASE_PATH);
  60. FileOutputStream os = null;
  61. InputStream is = null;
  62. // 判断文件夹是否存在,不存在就创建一个
  63. if (!dir.exists()) {
  64. dir.mkdirs();
  65. }
  66. try {
  67. // 得到数据库输出
  68. os = new FileOutputStream(databaseFilenames);
  69. // 得到数据文件的输入流
  70. is = context.getResources().openRawResource(R.raw.mzk_db);
  71. byte[] buffer = new byte[8192];
  72. int count = 0;
  73. while ((count = is.read(buffer)) != -1) {
  74. os.write(buffer,count);
  75. os.flush();
  76. }
  77. // 之所以不在这里初始化,是因为这边是静态的方法,而mSDB并没有设置为静态的,也不推荐设为静态的
  78. // mSDB = sqliteDatabase.openOrCreateDatabase(DATABASE_PATH +
  79. // dbName,null);
  80. } catch (Exception e) {
  81. e.printStackTrace();
  82. } finally {
  83. try {
  84. os.close();
  85. is.close();
  86. } catch (IOException e) {
  87. e.printStackTrace();
  88. }
  89.  
  90. }
  91.  
  92. }
  93.  
  94. /**
  95. * 判断数据库是否存在
  96. *
  97. * @return
  98. */
  99. private static boolean checkDataBase() {
  100. sqliteDatabase checkDB = null;
  101. String databaseFilename = DATABASE_PATH + dbName;
  102. // 要自己加上try catch方法
  103. try {
  104. // 返回最新的数据库
  105. checkDB = sqliteDatabase.openDatabase(databaseFilename,sqliteDatabase.OPEN_READONLY);
  106. } catch (sqliteException e) {
  107. // TODO: handle exception
  108. }
  109.  
  110. if (checkDB != null) {
  111. checkDB.close();
  112. }
  113. // 如果checkDB为null,则没有数据库,返回false
  114. return checkDB == null ? false : true;
  115. }
  116.  
  117. /**
  118. * 查询所有省份的信息
  119. *
  120. * @return 省份信息
  121. */
  122. public ArrayList<City> queryProvince() {
  123. // 创建数据库的实例
  124. mSDB = sqliteDatabase
  125. .openOrCreateDatabase(DATABASE_PATH + dbName,null);
  126. ArrayList<City> list = new ArrayList<City>();
  127. String sql = "select * from fs_province";
  128. Cursor cursor = mSDB.rawQuery(sql,null);
  129. while (cursor.moveToNext()) {
  130. City city = new City();
  131. String id = cursor.getString(cursor.getColumnIndex("ProvinceID"));
  132. String name = cursor.getString(cursor
  133. .getColumnIndex("ProvinceName"));
  134. city.setName(name);
  135. city.setId(id);
  136. list.add(city);
  137. }
  138. if (cursor != null) {
  139. cursor.close();
  140. }
  141. return list;
  142. }
  143.  
  144.  
  145. public void closeDataBase() {
  146. if (mSDB != null) {
  147. mSDB.close();
  148. }
  149. }
  150. }


我们看到,如果将数据库写到手机sd卡中,都不需要sqliteOpenHelper类了,而是直接通过

mSDB = sqliteDatabase.openOrCreateDatabase(DATABASE_PATH + dbName,null);就可以获得数据库的实例了。


但是这个方法有个缺点,就是不能进行数据库升级了。显然这样是非常不好的。

那么如果我们还想用sqliteOpenHelper,又将其写到sd卡中,又该怎么做呢。

下面的这段代码是有错误的,你只需要注意看51行,正是因为下面的代码,我才研究了onCreate方法到底什么时候执行。

  1. package jz.his.db;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.InputStreamReader;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12.  
  13. import jz.his.jzhis.R;
  14. import android.content.Context;
  15. import android.database.Cursor;
  16. import android.database.sqlite.sqliteDatabase;
  17. import android.database.sqlite.sqliteException;
  18. import android.database.sqlite.sqliteOpenHelper;
  19. import android.os.Environment;
  20. import android.util.Log;
  21.  
  22.  
  23.  
  24. public class CityInfoDataSupport extends sqliteOpenHelper
  25. {
  26. private final static String TAG = "CityInfoDataSupport";
  27. public static final String dbName = "cityego";
  28. // 数据库在手机里的路径
  29. private static String DATABASE_PATH = Environment
  30. .getExternalStorageDirectory().getAbsolutePath()+"/com.bcinfo.pwzs/";
  31. private static int version = 1;
  32. private final String GEOCODING_TABLE_NAME = "GEOCODING";
  33. private sqliteDatabase mSDB = getReadableDatabase();
  34. private static CityInfoDataSupport mDataSupport;
  35. Context context;
  36.  
  37. public static CityInfoDataSupport getInstance(Context context)
  38. {
  39. initDatabse(context);
  40. if (mDataSupport == null)
  41. {
  42. mDataSupport = new CityInfoDataSupport(context);
  43. }
  44. return mDataSupport;
  45. }
  46.  
  47. CityInfoDataSupport(Context context)
  48. {
  49. super(context,DATABASE_PATH+dbName,version);
  50. }
  51.  
  52. @Override
  53. public void onCreate(sqliteDatabase db)
  54. {
  55. executeAssetssql(db,"geocoding_create.sql");
  56. }
  57.  
  58. @Override
  59. public void onUpgrade(sqliteDatabase db,int newVersion)
  60. {
  61. String sql = "drop table if exits " + GEOCODING_TABLE_NAME;
  62. db.execsql(sql);
  63. onCreate(db);
  64. }
  65.  
  66. private void loadsql(sqliteDatabase db,String schemaName)
  67. {
  68. InputStream inputS;
  69. try
  70. {
  71. inputS = context.getAssets().open(schemaName);
  72. BufferedReader reader = new BufferedReader(new InputStreamReader(inputS));
  73. String sql = null;
  74. while ((sql = reader.readLine()) != null)
  75. {
  76. db.execsql(sql.replace(";",""));
  77. }
  78. reader.close();
  79. reader = null;
  80. }
  81. catch (IOException e)
  82. {
  83. // TODO Auto-generated catch block
  84. e.printStackTrace();
  85. }
  86. }
  87.  
  88. /**
  89. * 读取数据库文件(.sql),并执行sql语句
  90. * */
  91. private void executeAssetssql(sqliteDatabase db,String schemaName)
  92. {
  93. Log.e("DataSupport","executeAssetssql");
  94. BufferedReader in = null;
  95. try
  96. {
  97. in = new BufferedReader(new InputStreamReader(context.getAssets().open(schemaName)));
  98. String line;
  99. String buffer = "";
  100. while ((line = in.readLine()) != null)
  101. {
  102. buffer += line;
  103. if (line.trim().endsWith(";"))
  104. {
  105. db.execsql(buffer.replace(";",""));
  106. buffer = "";
  107. }
  108. }
  109. }
  110. catch (IOException e)
  111. {
  112. Log.e("db-error",e.toString());
  113. }
  114. finally
  115. {
  116. try
  117. {
  118. if (in != null)
  119. in.close();
  120. }
  121. catch (IOException e)
  122. {
  123. Log.e("db-error",e.toString());
  124. }
  125. }
  126. }
  127.  
  128. public synchronized void insertCityInfo()
  129. {
  130. loadsql(mSDB,"geocoding_data.txt");
  131. }
  132.  
  133. public synchronized List<City> queryDataById(String field,String id)
  134. {
  135. String sql = "";
  136. List<City> cityList = new ArrayList<City>();
  137. if (field.equals("grade"))
  138. {
  139. sql = "select * from " + GEOCODING_TABLE_NAME + " where grade = ? ";
  140. }
  141. else if (field.equals("parent"))
  142. {
  143. sql = "select * from " + GEOCODING_TABLE_NAME + " where parent = ? ";
  144. }
  145. String[] params = new String[]
  146. { id };
  147. Cursor c = mSDB.rawQuery(sql,params);
  148. while (c.moveToNext())
  149. {
  150. City city = new City();
  151. city.setGbCode(c.getString(c.getColumnIndex("gbcode")));
  152. city.setGbName(c.getString(c.getColumnIndex("gbname")));
  153. city.setGrade(c.getString(c.getColumnIndex("grade")));
  154. city.setLongitude(c.getString(c.getColumnIndex("longtitude")));
  155. city.setLatitude(c.getString(c.getColumnIndex("latitude")));
  156. city.setParent(c.getString(c.getColumnIndex("parent")));
  157. cityList.add(city);
  158. }
  159. if (c != null)
  160. {
  161. c.close();
  162. }
  163. return cityList;
  164. }
  165.  
  166. public void deleteAppTempTraffic()
  167. {
  168. String sql = "delete from " + GEOCODING_TABLE_NAME;
  169. mSDB.execsql(sql);
  170. }
  171.  
  172. public static void initDatabse(Context cntext)
  173. {
  174. boolean dbExist = checkDataBase();
  175. //判断数据库是否存在 不存在就把raw里的数据库写入手机
  176. if (!dbExist)
  177. {
  178. try
  179. {
  180. copyDataBase(cntext);
  181. }
  182. catch (IOException e)
  183. {
  184. throw new Error("Error copying database");
  185. }
  186. }
  187. }
  188.  
  189. /**
  190. * 判断数据库是否存在
  191. * @return false or true
  192. */
  193. public static boolean checkDataBase()
  194. {
  195. sqliteDatabase checkDB = null;
  196. try
  197. {
  198. String databaseFilename = DATABASE_PATH + dbName;
  199. checkDB = sqliteDatabase.openDatabase(databaseFilename,sqliteDatabase.OPEN_READONLY);
  200. }
  201. catch (sqliteException e)
  202. {
  203. }
  204. if (checkDB != null)
  205. {
  206. checkDB.close();
  207. }
  208. return checkDB != null ? true : false;
  209. }
  210.  
  211. /**
  212. * 复制数据库到手机指定文件夹下
  213. * @throws IOException
  214. */
  215. public static void copyDataBase(Context context) throws IOException
  216. {
  217. String databaseFilenames = DATABASE_PATH + dbName;
  218. File dir = new File(DATABASE_PATH);
  219. FileOutputStream os = null;
  220. // 判断文件夹是否存在,不存在就新建一个
  221. if (!dir.exists())
  222. {
  223. dir.mkdirs();
  224. }
  225. try
  226. {
  227. // 得到数据库文件的写入流
  228. os = new FileOutputStream(databaseFilenames);
  229. }
  230. catch (FileNotFoundException e)
  231. {
  232. e.printStackTrace();
  233. }
  234. // 得到数据库文件的数据流
  235. InputStream is = context.getResources().openRawResource(R.raw.cityego);
  236. byte[] buffer = new byte[8192];
  237. int count = 0;
  238. try
  239. {
  240. while ((count = is.read(buffer)) > 0)
  241. {
  242. os.write(buffer,count);
  243. os.flush();
  244. }
  245. }
  246. catch (IOException e)
  247. {
  248. }
  249. try
  250. {
  251. is.close();
  252. os.close();
  253. }
  254. catch (IOException e)
  255. {
  256. e.printStackTrace();
  257. }
  258. }
  259. }

通过上面的这个代码,我的onCreate方法一直没有执行。最终经过我多次试验,我知道了问题所在,所以在这里进行总结。


那么onCreate方法到底什么时候执行呢?

sqliteOpenHelper的onCreate方法一定是在getReadableDatabase方法之后的

sqliteDatabase mSDB = getReadableDatabase()这个方法首先检查手机中,是否有已经存在的数据库,如果没有,则执行onCreate方法,如果有,则不执行---->但是,这里有个前提是,你的supre(context,version),的第二个参数不能是已存在的数据库路径。

我这里,将第二个参数,弄成了已存在的数据库文件,所以onCreate方法永远不会执行。


那么当super(context,dbName,version);第二个参数正确和并且执行了getReadableDatabase这个方法,才会在系统内存有数据库


折磨了我一个下午啊啊啊啊。

猜你在找的Sqlite相关文章