Question

I have an app that comes with a bunch of small images (about 200 images) (~10MB total size) to be displayed on screen in different cases. When the user presses some button, one of these images is displayed (could be anyone of them). At any time in the future more images might be added, so the app checks an xml document on a server (this check is done in onCreate() of the main activity if it is at least 24 hours since the check was last done). The xml document lists all the images, so it is easy to check if the document was changed and new images added. In case more images were added, the app will download these images from the server and should store them with the images that already exists on the device.

My first thought was to bundle the 10MB of images with the app, putting them in the assets folder and the first time the app would start, the images would be moved from the assets folder to the internal storage. Then if any more images were to be added in the future, they would be downloaded and saved in the internal storage as well, so all the images were nicely tugged together, however after a bit of experimenting, I discovered that it takes a lot of time for the device (testing on HTC One S with Android 4.1) just to list the images in the assets folder (more than one minute), never mind actually copying them. This is unacceptable, since I don't wan't the users first experience of the app to be over a minute of waiting time.

I am using the list(String path) method of the AssetManager class to list the files.

So I guess my question is:

How would you go about implementing this in a way so that the user does not have to wait for a long time on the first launch and the app would still be able to download more images on the fly?

Was it helpful?

Solution

I have a similar scenario, I zipped all the files on a single zip and stored it on the res/raw folder. Then on the first startup I extract all the files to the app's internal storage.

public static void unzipFiles(Context context, int file) {
    InputStream stream;

    context.getFilesDir().mkdirs();
    String path = context.getFilesDir().getAbsolutePath();

    try {
        stream = context.getResources().openRawResource(file);
        if (stream == null) {
            throw new RuntimeException("Cannot load " + file + " file from raw folder");
        }

        ZipInputStream zis = new ZipInputStream(stream);
        ZipEntry entry;

        while ((entry = zis.getNextEntry()) != null) {
            if (entry.isDirectory()) {
                File f = new File(path, entry.getName());
                if (!f.exists()) {
                    f.mkdirs();
                }
            } else {
                int size;
                byte[] buffer = new byte[2048];

                File f = new File(path, entry.getName());
                FileOutputStream fos = new FileOutputStream(f);
                BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

                while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                }
                bos.flush();
                bos.close();
            }
        }

    } catch (IOException e) {
        throw new RuntimeException("Cannot unzip '" + file + "'", e);
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top