我有一个应用程序,附带了一堆小图像(约200图像)(~10MB总大小)在屏幕上显示在不同的情况下。当用户按下某个按钮时,将显示这些图像中的一个(可以是其中任何一个)。在未来的任何时候,可能会添加更多的图像,所以应用程序检查服务器上的xml文档(这个检查是在主活动的onCreate()中完成的,如果它是至少24小时后完成的最后一次检查)。xml文档列出了所有图像,因此很容易检查是否更改了文档并添加了新图像。如果添加了更多的图像,应用程序将从服务器下载这些图像,并将它们与设备上已经存在的图像一起存储。
我的第一个想法是将10MB的图像与应用程序捆绑在一起,将它们放在资产文件夹中,并且应用程序第一次启动时,图像将从资产文件夹移动到内部存储。然后,如果将来要添加更多的图像,它们也会被下载并保存在内部存储中,所以所有的图像都被很好地拉在一起,但是经过一些实验,我发现设备花费了很多时间(在Android 4.1的HTC One S上测试),只是列出资产文件夹中的图像(超过一分钟),更不用说实际复制它们了。这是不可接受的,因为我不希望用户的第一次体验是超过一分钟的等待时间。
我使用AssetManager类的list(字符串路径)方法来列出文件。
所以我想我的问题是:
你将如何实现这一点,使用户不必等待很长时间的第一次启动,应用程序仍然能够下载更多的图像在飞行?
我有一个类似的场景,我将所有文件压缩到一个zip文件中,并将其存储在res/raw文件夹中。然后在第一次启动时,我将所有文件提取到应用程序的内部存储中。
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);
}
}