2

I want to use pre-loaded sqlite database which is as big as 250 Megabytes. I have copied the database into assets folder. Since we can not access the assets database directly, I am copying the database from assets into "context.getFilesDir()" folder.
Using this strategy my app works well for small database up to 5-6 megabytes but app crashes if I do so for large database, which is what I want.

Is there any better way or something wrong with what I am trying to do? I have already tried solutions of the possible copies Android: Accessing assets folder sqlite database file with .sqlite extension Getting a column from .sqlite containing multiple tables with multiple columns How to use preloaded SQLite database in Android from Assets

My code for SqliteHelper is given below for reference.

package com.example.database;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;

/**
 * Created by MOHIT on 06-08-2014.
 */
public class SQLiteHelper  {
    private static final String DB_NAME = "alldb.sqlite";
    //private String DB_NAME = "alldb.sqlite";

    private Context context;
    private SQLiteDatabase database;
    public SQLiteHelper(Context context) {
        this.context = context;
    }

    public SQLiteDatabase openDatabase() {
        File dbFile = new File(context.getFilesDir(), DB_NAME);

        if (!dbFile.exists()) {
            try {
                copyDatabase(dbFile);
            } catch (IOException e) {
           //     Utilities.makeToastLong(context, "Error here");
                throw new RuntimeException("Error creating source database", e);

            }
        }

        database= SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);

        return database;

    }
    public void closeDatabase()
    {
        if(database!=null&& database.isOpen())
          database.close();
    }

    private void copyDatabase(File dbFile) throws IOException {

        try {

            InputStream is = context.getAssets().open(DB_NAME);
            dbFile.createNewFile();
            OutputStream os = new FileOutputStream(dbFile,false);

            byte[] buffer = new byte[1024];
            while (is.read(buffer) > 0) {
                os.write(buffer);
            }

            os.flush();
            os.close();
            is.close();
        }catch (Exception e)
        {
            Log.e(SQLiteHelper.class.getSimpleName()," Error in Database copy "+e.getLocalizedMessage());

        }
    }
}
Community
  • 1
  • 1
  • 1
    is it crashing while coping? – KOTIOS Aug 27 '14 at 04:28
  • 1
    Crashes? How? Can we see a crash? – G. Blake Meike Aug 27 '14 at 04:33
  • @DIVA yes it is crashing with SQLiteDatabaseCorruptException http://developer.android.com/reference/android/database/sqlite/SQLiteDatabaseCorruptException.html – eternal_developer Aug 27 '14 at 04:49
  • i guess there is issue in copying..is it woking for small size db? hv u done any upgrade recently on db? – KOTIOS Aug 27 '14 at 04:54
  • No upgrades on Db and yes its working excellent for small size DB. – eternal_developer Aug 27 '14 at 05:00
  • How about compressing your db file and storing that in your assets. I am not sure, but this could give you a sizeable reduction in space. Once the app gets installed, copy and unzip the compressed file from assets to a temporary path and load it from there. P.S. I am wondering what data you would be having worth 250Megs for a mobile application. Should you revisit your design strategy? – midhunhk Aug 27 '14 at 05:17

2 Answers2

0

I read in a lot of other topics that the size limit for the pre-loaded SQLite DB is 50Megabytes. To bypass this limit you can:

1-Copy the DB to external folder

2-From external folder, you copy the DB to your internalStorage /data/data/yourApp

3-check at start up if the DB exists, if not copy it

Limitation on Google Blog . You may need to use the Expansion File for your DB

113408
  • 3,364
  • 6
  • 27
  • 54
0

This this code, through org.apache.commons.io.IOUtils.

public static void initialize(Context context) {
    File dbFile = getDatabaseAbsolutePath(context);
    if (!dbFile.exists()) {
        if (Ln.isDebugEnabled()) Ln.i("###### Copying preloaded DATABASE to: "+dbFile.getAbsolutePath());
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            is = context.getAssets().open("init.db");
            fos = new FileOutputStream(dbFile);
            IOUtils.copy(is, fos);
        } catch (Exception e) {
            if ( Ln.isDebugEnabled()) e.printStackTrace();
        } finally {
            try {
                if (is != null) is.close();
                if (fos != null) fos.close();
            } catch(Exception e) {}
        }
    }
}
Martín Alcubierre
  • 4,341
  • 1
  • 27
  • 27