2010-10-26 103 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(); 
相关问题