Copying large database from assets in Android
Sometimes to make database and populating data. in it may take heavy time like 5 minutes or more, which is a lot so in such cases we can make our database in seperate application and copy it in Project ,which is done quickly.
private void copyDataBase() throws IOException { // Open your local db as the input stream InputStream myInput = myContext.getAssets().open(DB_NAME); // Path to the just created empty db String outFileName = DB_PATH + DB_NAME; // Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(outFileName); // transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } // Close the streams myOutput.flush(); myOutput.close(); myInput.close(); }
So ,above steps are clear and simple taking a input stream from available database directory and writing it in our project’s directory using outputstream ,but the problem is visible when dealing with databases > 1.5 mb. IOExceptionis thrown even if there is a check :myOutput.available()
which returns correct no of byte,but when we try to read bytes,it generates IOException.
Why IOException in this Case:
First of all let’s discuss general hierarchy of an Android project as here, the problem is closely binded with the hierarchy itself.General android project contains resources
(raw xml files,DB files ,drawables,string values,layout for UI screens),java source files, Android manifest(all android components declaration ,permission…. etc),generated R file ,libraries(optional).
Now java source file are compiled by DVM(Dalvik virtual machine , a layer upon java virtual machine as JVM is Heavy for mobile devices) and converted to .dex files.Resources(raw xml files,Db files,dra–wables,string values,layout for screens),Android manifest are bundled or packaged or zipped by AAPT. Then .dex files and android packaged files are merged to make .apk which is used by end user to install application on Android mobile.
AAPT (Android assets packaging tool) is responsible for creating this bundle, which we can think of as a ZIP file with a particular layout that the Android OS can understand.As part of preparing our APK, aapt selectively compresses various assets to save space on
the device. The way aapt determines which assets need compression is by their file extension. The following code, taken from Package.cpp in the aapt source code,
sheds some light on which types of files are not compressed by default:
/* these formats are already compressed, or don’t compress well */
static const char* kNoCompressExt[] = {
“.jpg”, “.jpeg”, “.png”, “.gif”,
“.wav”, “.mp2”, “.mp3”, “.ogg”, “.aac”,
“.mpg”, “.mpeg”, “.mid”, “.midi”, “.smf”, “.jet”,
“.rtttl”, “.imy”, “.xmf”, “.mp4”, “.m4a”,
“.m4v”, “.3gp”, “.3gpp”, “.3g2”, “.3gpp2”,
“.amr”, “.awb”, “.wma”, “.wmv”
};
How to solve problem:
We can give our asset file an extension in the list above. The other option is to pass a specific extension to the -0 flag,such as -0 db, to disable compression for assets with that
extension. We can pass the -0 flagmultiple times, and each time with a separate extension,if We need more than one type to be uncompressed.