因為這次的項目需要自帶數據,所以就就把數據都放到一個SQLite的數據庫文件中了,之后把該文件放到了assets文件夾下面。一開始打算每次都從assets文件夾下面把該文件夾拷貝到手機的SD卡或者手機自身的存儲上之后再使用,后來考慮到每次都拷貝的話效率不高,並且如果涉及到對數據庫的修改操作的話拷貝之后數據就被恢復了。
因此就寫了該封裝,該封裝只是在第一次使用數據庫文件的時候把該文件夾拷貝到手機的/data/data/應用程序報名/database文件夾下,之后就直接從這個地方使用了。並且它允許你直接通過assets文件夾下的數據庫名稱來獲取SQLiteDatabase對象,這樣就極大的方便了你對數據庫的使用。
- package com.jemsn.database;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.HashMap;
- import java.util.Map;
- import android.content.Context;
- import android.content.SharedPreferences;
- import android.content.res.AssetManager;
- import android.database.sqlite.SQLiteDatabase;
- import android.util.Log;
- /**
- * This is a Assets Database Manager
- * Use it, you can use a assets database file in you application
- * It will copy the database file to "/data/data/[your application package name]/database" when you first time you use it
- * Then you can get a SQLiteDatabase object by the assets database file
- * @author RobinTang
- * @time 2012-09-20
- *
- *
- * How to use:
- * 1. Initialize AssetsDatabaseManager
- * 2. Get AssetsDatabaseManager
- * 3. Get a SQLiteDatabase object through database file
- * 4. Use this database object
- *
- * Using example:
- * AssetsDatabaseManager.initManager(getApplication()); // this method is only need call one time
- * AssetsDatabaseManager mg = AssetsDatabaseManager.getManager(); // get a AssetsDatabaseManager object
- * SQLiteDatabase db1 = mg.getDatabase("db1.db"); // get SQLiteDatabase object, db1.db is a file in assets folder
- * db1.??? // every operate by you want
- * Of cause, you can use AssetsDatabaseManager.getManager().getDatabase("xx") to get a database when you need use a database
- */
- public class AssetsDatabaseManager {
- private static String tag = "AssetsDatabase"; // for LogCat
- private static String databasepath = "/data/data/%s/database"; // %s is packageName
- // A mapping from assets database file to SQLiteDatabase object
- private Map<String, SQLiteDatabase> databases = new HashMap<String, SQLiteDatabase>();
- // Context of application
- private Context context = null;
- // Singleton Pattern
- private static AssetsDatabaseManager mInstance = null;
- /**
- * Initialize AssetsDatabaseManager
- * @param context, context of application
- */
- public static void initManager(Context context){
- if(mInstance == null){
- mInstance = new AssetsDatabaseManager(context);
- }
- }
- /**
- * Get a AssetsDatabaseManager object
- * @return, if success return a AssetsDatabaseManager object, else return null
- */
- public static AssetsDatabaseManager getManager(){
- return mInstance;
- }
- private AssetsDatabaseManager(Context context){
- this.context = context;
- }
- /**
- * Get a assets database, if this database is opened this method is only return a copy of the opened database
- * @param dbfile, the assets file which will be opened for a database
- * @return, if success it return a SQLiteDatabase object else return null
- */
- public SQLiteDatabase getDatabase(String dbfile) {
- if(databases.get(dbfile) != null){
- Log.i(tag, String.format("Return a database copy of %s", dbfile));
- return (SQLiteDatabase) databases.get(dbfile);
- }
- if(context==null)
- return null;
- Log.i(tag, String.format("Create database %s", dbfile));
- String spath = getDatabaseFilepath();
- String sfile = getDatabaseFile(dbfile);
- File file = new File(sfile);
- SharedPreferences dbs = context.getSharedPreferences(AssetsDatabaseManager.class.toString(), 0);
- boolean flag = dbs.getBoolean(dbfile, false); // Get Database file flag, if true means this database file was copied and valid
- if(!flag || !file.exists()){
- file = new File(spath);
- if(!file.exists() && !file.mkdirs()){
- Log.i(tag, "Create \""+spath+"\" fail!");
- return null;
- }
- if(!copyAssetsToFilesystem(dbfile, sfile)){
- Log.i(tag, String.format("Copy %s to %s fail!", dbfile, sfile));
- return null;
- }
- dbs.edit().putBoolean(dbfile, true).commit();
- }
- SQLiteDatabase db = SQLiteDatabase.openDatabase(sfile, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
- if(db != null){
- databases.put(dbfile, db);
- }
- return db;
- }
- private String getDatabaseFilepath(){
- return String.format(databasepath, context.getApplicationInfo().packageName);
- }
- private String getDatabaseFile(String dbfile){
- return getDatabaseFilepath()+"/"+dbfile;
- }
- private boolean copyAssetsToFilesystem(String assetsSrc, String des){
- Log.i(tag, "Copy "+assetsSrc+" to "+des);
- InputStream istream = null;
- OutputStream ostream = null;
- try{
- AssetManager am = context.getAssets();
- istream = am.open(assetsSrc);
- ostream = new FileOutputStream(des);
- byte[] buffer = new byte[1024];
- int length;
- while ((length = istream.read(buffer))>0){
- ostream.write(buffer, 0, length);
- }
- istream.close();
- ostream.close();
- }
- catch(Exception e){
- e.printStackTrace();
- try{
- if(istream!=null)
- istream.close();
- if(ostream!=null)
- ostream.close();
- }
- catch(Exception ee){
- ee.printStackTrace();
- }
- return false;
- }
- return true;
- }
- /**
- * Close assets database
- * @param dbfile, the assets file which will be closed soon
- * @return, the status of this operating
- */
- public boolean closeDatabase(String dbfile){
- if(databases.get(dbfile) != null){
- SQLiteDatabase db = (SQLiteDatabase) databases.get(dbfile);
- db.close();
- databases.remove(dbfile);
- return true;
- }
- return false;
- }
- /**
- * Close all assets database
- */
- static public void closeAllDatabase(){
- Log.i(tag, "closeAllDatabase");
- if(mInstance != null){
- for(int i=0; i<mInstance.databases.size(); ++i){
- if(mInstance.databases.get(i)!=null){
- mInstance.databases.get(i).close();
- }
- }
- mInstance.databases.clear();
- }
- }
- }
使用的過程也很簡單,應用程序開始的時候初始化一下,之后就可以在任意地方獲取管理器在通過assets文件夾下的數據庫文件名直接獲取SQLiteDatabase對象,之后對數據庫的操作就完全看你了。。。
簡單的使用例子:
- // 初始化,只需要調用一次
- AssetsDatabaseManager.initManager(getApplication());
- // 獲取管理對象,因為數據庫需要通過管理對象才能夠獲取
- AssetsDatabaseManager mg = AssetsDatabaseManager.getManager();
- // 通過管理對象獲取數據庫
- SQLiteDatabase db1 = mg.getDatabase("db1.db");
- // 對數據庫進行操作
- db1.execSQL("insert into tb([ID],[content]) values(null, 'db1');");
需要注意的是獲取數據庫對象的時候是區分數據庫文件名的大小寫的。
