Android如何复制所有安装时Play Asset Delivery文件至应用文件系统?
解决Play Asset Delivery资源目录复制问题
原代码无法运行的原因很明确:
- AssetManager不支持直接打开根目录
"/",根目录需用空字符串""表示; open()方法仅能打开单个文件,无法处理目录结构,直接复制流的方式对目录完全无效。
可行方案:递归遍历Assets目录并复制
通过递归遍历Assets中的所有文件和子目录,在本地文件系统创建对应目录结构,再逐个复制文件内容。
核心工具函数(Kotlin)
fun copyAssetsDir(assetManager: AssetManager, srcDir: String, destDir: File) { // 创建目标目录,不存在则递归创建 if (!destDir.exists()) { destDir.mkdirs() } // 获取当前Assets目录下的所有条目 val entries = assetManager.list(srcDir) ?: return for (entry in entries) { val srcPath = if (srcDir.isEmpty()) entry else "$srcDir/$entry" val destFile = File(destDir, entry) // 判断条目是目录还是文件:调用list()返回非null则为目录 val subEntries = assetManager.list(srcPath) if (subEntries != null) { // 递归复制子目录 copyAssetsDir(assetManager, srcPath, destFile) } else { // 复制单个文件,使用use自动关闭流 assetManager.open(srcPath).use { inputStream -> FileOutputStream(destFile).use { outputStream -> inputStream.copyTo(outputStream) } } } } }
调用示例
在Activity或Fragment中调用,建议在IO线程执行避免阻塞主线程:
// 目标目录:应用内部存储的gamedata文件夹(无需额外权限) val destDir = File(filesDir, "gamedata") // 使用协程在IO线程执行复制 lifecycleScope.launch(Dispatchers.IO) { // 复制Assets根目录下的所有资源到目标目录 copyAssetsDir(assets, "", destDir) // 复制完成后切换到主线程处理后续逻辑 withContext(Dispatchers.Main) { // 例如:启动游戏、显示资源准备完成提示 } } // 如果游戏资源在Assets的子目录(如assets/game_res),则调用: // copyAssetsDir(assets, "game_res", destDir)
注意事项
- 若要将资源复制到外部存储(如
Environment.getExternalStorageDirectory()),需申请WRITE_EXTERNAL_STORAGE权限,并处理Android 6.0+的动态权限请求。 - Install-Time类型的Play Asset Delivery资源会直接打包到APK的Assets目录,可通过AssetManager直接访问,无需额外解压步骤。
内容的提问来源于stack exchange,提问作者Bungles
相关产品推荐
相关产品推荐

