2010-10-26 35 views

回答

10

我找到的一個很好的例子:Using your own SQLite database in Android applications

基本上,你所創建的數據庫導出爲一個SQL文件,並將其存儲在資產的文件夾。 在第一次程序啓動時,將文件的數據導入到最終數據庫中。

我認爲這是最好的方法,但是你的數據會在apk和數據庫中出現兩次,使用更多的存儲空間。

+1

好文章,是有益的 – schwiz 2010-10-26 12:41:32

8

我剛剛開始爲Android開發,驚奇地發現綁定一個靜態數據庫是不容易的。所以我做了唯一合理的事情:創建了一個能夠做到這一點的圖書館。用法示例:

import android.database.sqlite.SQLiteDatabase; 
import kiwidrew.staticdb.StaticDatabase; 

public class BlahBlah extends Activity { 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    SQLiteDatabase db = StaticDatabase.openDatabase(this, "assets/foobar.db"); 
    // Do normal database stuff with 'db'... 
    } 
} 

你得到一個標準SQLiteDatabase對象,唯一的限制是它不支持寫入。 (顯然!)

請注意,這將失敗,除非數據庫存儲在您的.apk沒有壓縮。使用aapt -0命令添加SQLite數據庫或修改build.xml<nocompress extension="db" />標誌傳遞給<aapt>標籤...

http://bitbucket.org/kiwidrew/android-staticdb獲取代碼。

注意:我已經完全寫完了,而且迄今爲止只做了非常基本的測試。錯誤報告將不勝感激!

1

沒有任何簡單的方法直接從資產中讀取數據庫。您應該在首次運行時將數據庫從資產複製到數據文件夾,然後每次啓動應用程序時,都應該檢查數據文件夾中的數據庫,並在數據庫不存在時再次複製數據庫。

這些步驟可以幫助你:

1)你的數據庫上執行這些命令,如果android_metadata表不存在於數據庫中,機器人無法打開您的數據庫:

CREATE TABLE android_metadata(locale TEXT DEFAULT 'en_US') 
INSERT INTO android_metadata VALUES('en_US') 

2)組塊您的數據庫,因爲android不支持從資產中讀取超過1 MB大小的文件。

這條巨蟒大塊代碼數據庫:

def chunk_file(file_name): 
    input_file = open(file_name, "rb") 

    chunk_counter = 0; 
    while True: 
     chunk = input_file.read(512 * 1024) # 512 KB 
     if chunk: 
      output_file_name = file_name + "." + str(chunk_counter).zfill(4) 

      output_file = open(output_file_name, "wb") 
      output_file.write(chunk) 
      output_file.close() 

      chunk_counter += 1 
     else: 
      break 

    input_file.close() 
    return 

# Input: database.db 
# Output: database.db.0000, database.db.0001, database.db.0002, ... 
chunk_file("database.db") 

然後把database.db.0000,database.db.0001,database.db.0002,...在資產的文件夾。

3)應用程序啓動時,數據文件夾中存在檢查數據庫。

public static boolean databaseExists() { 

    boolean result = false; 

    SQLiteDatabase checkDB = null; 

    try { 
     checkDB = SQLiteDatabase.openDatabase(
       getApplicationContext().getFilesDir().getPath() + "/database.db", 
       null, SQLiteDatabase.OPEN_READONLY); 
     result = true; 
    } catch (SQLiteException exception) { 
     result = false; 
    } 

    if (checkDB != null) { 

     checkDB.close(); 

    } 

    return result; 
} 

4)如果數據庫中不存在數據庫,則將數據庫從資產複製到數據文件夾中。

public static void copyDatabase() throws IOException { 
    AssetManager assets = getApplicationContext().getAssets(); 

    // database.db.0000, database.db.0001, database.db.0002, ... --> databaseChunks. 
    String[] databaseChunks = assets.list(""); 
    Arrays.sort(databaseChunks); 

    OutputStream databaseStream = new FileOutputStream(
      getApplicationContext().getFilesDir().getPath() + "/database.db"); 

    for (int i = 0; i < databaseChunks.length; i++) { 
     String databaseChunkName = databaseChunks[i]; 

     InputStream chunkStream = assets.open(databaseChunkName); 

     int length; 
     byte[] buffer = new byte[1024]; 
     while ((length = chunkStream.read(buffer)) > 0) { 
      databaseStream.write(buffer, 0, length); 
     } 

     chunkStream.close(); 
    } 

    databaseStream.close(); 

    return; 
} 

5)您可以連接到現在的數據庫:

SQLiteDatabase database = SQLiteDatabase.openDatabase(
      getApplicationContext().getFilesDir().getPath() + "/database.db", 
      null, SQLiteDatabase.OPEN_READONLY); 
// ... 
database.close(); 
相關問題