因为这次的项目需要自带数据,所以就就把数据都放到一个SQLite的数据库文件中了,之后把该文件放到了assets文件夹下面。一开始打算每次都从assets文件夹下面把该文件夹拷贝到手机的SD卡或者手机自身的存储上之后再使用,后来考虑到每次都拷贝的话效率不高,并且如果涉及到对数据库的修改操作的话拷贝之后数据就被恢复了。
因此就写了该封装,该封装只是在第一次使用数据库文件的时候把该文件夹拷贝到手机的/data/data/应用程序报名/database文件夹下,之后就直接从这个地方使用了。并且它允许你直接通过assets文件夹下的数据库名称来获取SQLiteDatabase对象,这样就极大的方便了你对数据库的使用。
封装如下:
3 import java.io.InputStream; 4 import java.io.OutputStream; 5 import java.util.HashMap; 6 import java.util.Map; 7 8 import android.content.Context; 9 import android.content.SharedPreferences; 10 import android.content.res.AssetManager; 11 import android.database.sqlite.SQLiteDatabase; 12 import android.util.Log; 13 14 /** 15 * This is a Assets Database Manager 16 * Use it, you can use a assets database file in you application 17 * It will copy the database file to "/data/data/[your application package name]/database" when you first time you use it 18 * Then you can get a SQLiteDatabase object by the assets database file 19 * @author RobinTang 20 * @time 2012-09-20 21 * 22 * 23 * How to use: 24 * 1. Initialize AssetsDatabaseManager 25 * 2. Get AssetsDatabaseManager 26 * 3. Get a SQLiteDatabase object through database file 27 * 4. Use this database object 28 * 29 * Using example: 30 * AssetsDatabaseManager.initManager(getApplication()); // this method is only need call one time 31 * AssetsDatabaseManager mg = AssetsDatabaseManager.getManager(); // get a AssetsDatabaseManager object 32 * SQLiteDatabase db1 = mg.getDatabase("db1.db"); // get SQLiteDatabase object, db1.db is a file in assets folder 33 * db1.??? // every operate by you want 34 * Of cause, you can use AssetsDatabaseManager.getManager().getDatabase("xx") to get a database when you need use a database 35 */ 36 public class AssetsDatabaseManager { 37 private static String tag = "AssetsDatabase"; // for LogCat 38 private static String databasepath = "/data/data/%s/database"; // %s is packageName 39 41 // A mapping from assets database file to SQLiteDatabase object 42 private Map<String, SQLiteDatabase> databases = new HashMap<String, SQLiteDatabase>(); 43 44 // Context of application 45 private Context context = null; 46 47 // Singleton Pattern 48 private static AssetsDatabaseManager mInstance = null; 49 50 /** 51 * Initialize AssetsDatabaseManager 52 * @param context, context of application 53 */ 54 public static void initManager(Context context){ 55 if(mInstance == null){ 56 mInstance = new AssetsDatabaseManager(context); 57 } 58 } 59 60 /** 61 * Get a AssetsDatabaseManager object 62 * @return, if success return a AssetsDatabaseManager object, else return null 63 */ 64 public static AssetsDatabaseManager getManager(){ 65 return mInstance; 66 } 67 68 private AssetsDatabaseManager(Context context){ 69 this.context = context; 70 } 71 72 /** 73 * Get a assets database, if this database is opened this method is only return a copy of the opened database 74 * @param dbfile, the assets file which will be opened for a database 75 * @return, if success it return a SQLiteDatabase object else return null 76 */ 77 public SQLiteDatabase getDatabase(String dbfile) { 78 if(databases.get(dbfile) != null){ 79 Log.i(tag, String.format("Return a database copy of %s", dbfile)); 80 return (SQLiteDatabase) databases.get(dbfile); 81 } 82 if(context==null) 83 return null; 84 85 Log.i(tag, String.format("Create database %s", dbfile)); 86 String spath = getDatabaseFilepath(); 87 String sfile = getDatabaseFile(dbfile); 88 89 File file = new File(sfile); 90 SharedPreferences dbs = context.getSharedPreferences(
AssetsDatabaseManager.class.toString(), 0);
// Get Database file flag, if true means this database file was copied and valid
91 boolean flag = dbs.getBoolean(dbfile, false); 92 if(!flag || !file.exists()){ 93 file = new File(spath); 94 if(!file.exists() && !file.mkdirs()){ 95 Log.i(tag, "Create ""+spath+"" fail!"); 96 return null; 97 } 98 if(!copyAssetsToFilesystem(dbfile, sfile)){ 99 Log.i(tag, String.format("Copy %s to %s fail!", dbfile, sfile)); 100 return null; 101 } 103 dbs.edit().putBoolean(dbfile, true).commit(); 104 } 105 106 SQLiteDatabase db = SQLiteDatabase.openDatabase(sfile, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
107 if(db != null){
108 databases.put(dbfile, db);
109 }
110 return db;
111 }
112
113 private String getDatabaseFilepath(){
114 return String.format(databasepath, context.getApplicationInfo().packageName);
115 }
116
117 private String getDatabaseFile(String dbfile){
118 return getDatabaseFilepath()+"/"+dbfile;
119 }
120
121 private boolean copyAssetsToFilesystem(String assetsSrc, String des){
122 Log.i(tag, "Copy "+assetsSrc+" to "+des);
123 InputStream istream = null;
124 OutputStream ostream = null;
125 try{
126 AssetManager am = context.getAssets();
127 istream = am.open(assetsSrc);
128 ostream = new FileOutputStream(des);
129 byte[] buffer = new byte[1024];
130 int length;
131 while ((length = istream.read(buffer))>0){
132 ostream.write(buffer, 0, length);
133 }
134 istream.close();
135 ostream.close();
136 }
137 catch(Exception e){
138 e.printStackTrace();
139 try{
140 if(istream!=null)
141 istream.close();
142 if(ostream!=null)
143 ostream.close();
144 }
145 catch(Exception ee){
146 ee.printStackTrace();
147 }
148 return false;
149 }
150 return true;
151 }
152
153 /**
154 * Close assets database
155 * @param dbfile, the assets file which will be closed soon
156 * @return, the status of this operating
157 */
158 public boolean closeDatabase(String dbfile){
159 if(databases.get(dbfile) != null){
160 SQLiteDatabase db = (SQLiteDatabase) databases.get(dbfile);
161 db.close();
162 databases.remove(dbfile);
163 return true;
164 }
165 return false;
166 }
167
168 /**
169 * Close all assets database
170 */
171 static public void closeAllDatabase(){
172 Log.i(tag, "closeAllDatabase");
173 if(mInstance != null){
174 for(int i=0; i<mInstance.databases.size(); ++i){
175 if(mInstance.databases.get(i)!=null){
176 mInstance.databases.get(i).close();
177 }
178 }
179 mInstance.databases.clear();
180 }
181 }
182 }
使用的过程也很简单,应用程序开始的时候初始化一下,之后就可以在任意地方获取管理器在通过assets文件夹下的数据库文件名直接获取SQLiteDatabase对象,之后对数据库的操作就完全看你了。。。
简单的使用例子:
1 // 初始化,只需要调用一次 2 AssetsDatabaseManager.initManager(getApplication()); 3 // 获取管理对象,因为数据库需要通过管理对象才能够获取 4 AssetsDatabaseManager mg = AssetsDatabaseManager.getManager(); 5 // 通过管理对象获取数据库 6 SQLiteDatabase db1 = mg.getDatabase("db1.db"); 7 // 对数据库进行操作 8 db1.execSQL("insert into tb([ID],[content]) values(null, 'db1');");
需要注意的是获取数据库对象的时候是区分数据库文件名的大小写的。