如何改写Android应用assets文件夹中的config.json文件?
嘿,这个问题我之前也碰到过!其实核心原因是Android的assets文件夹是只读目录——APK安装后,这个目录里的文件会被打包在APK里,根本没法直接修改或覆盖。所以得换个思路,把配置文件放到可读写的存储位置,下面给你一套完整的解决方案:
解决方案思路
我们把assets里的默认config.json复制到应用的内部存储(无需额外权限,安全私密),之后所有的更新操作都针对这个可读写的文件;读取配置时,优先用存储里的版本,没有的话再用assets里的默认配置。
步骤1:把默认配置复制到内部存储
先写个方法,在应用启动时(比如Activity的onCreate)调用,确保默认配置存在:
private void copyDefaultConfigToStorage() { File configFile = new File(getActivity().getFilesDir(), "config.json"); // 已存在就不用重复复制了 if (configFile.exists()) { return; } try (InputStream is = getActivity().getAssets().open("config.json"); OutputStream os = new FileOutputStream(configFile)) { byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } } catch (IOException e) { e.printStackTrace(); // 这里可以加异常提示,比如配置初始化失败 } }
步骤2:从服务器拉取内容并更新存储文件
当你拿到服务器返回的JSON字符串后,直接写入内部存储的config.json覆盖旧内容:
private void updateConfigFromServer(String newJsonContent) { File configFile = new File(getActivity().getFilesDir(), "config.json"); try (FileWriter writer = new FileWriter(configFile)) { writer.write(newJsonContent); writer.flush(); // 这里可以加更新成功的逻辑,比如给用户提示 } catch (IOException e) { e.printStackTrace(); // 处理写入失败的情况 } }
比如你示例里的JSON字符串{ "id": 1, "name": "A green door", "price": 12.50, "tags": ["home", "green"] },直接传给这个方法就行。
步骤3:改进读取逻辑,优先读存储里的配置
把你原来的读取方法改成下面这样,优先取存储里的最新配置,没有再读assets的默认值:
public String loadConfig() { // 先尝试读取内部存储的配置 File configFile = new File(getActivity().getFilesDir(), "config.json"); if (configFile.exists()) { try (BufferedReader reader = new BufferedReader(new FileReader(configFile))) { StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } return sb.toString(); } catch (IOException e) { e.printStackTrace(); } } // 存储里没有的话,读取assets的默认配置 String json = null; try { InputStream is = getActivity().getAssets().open("config.json"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); json = new String(buffer, StandardCharsets.UTF_8); } catch (IOException ex) { ex.printStackTrace(); return null; } return json; }
小补充
- 内部存储的
getFilesDir()是应用私有目录,其他应用碰不到,卸载应用时会一起删除,很适合存私有配置。 - 如果要放到外部存储(比如让用户手动修改),Android 10及以上要用Scoped Storage,无需权限但有路径限制;低版本需要申请存储权限,不过一般私有配置用内部存储就够了。
内容的提问来源于stack exchange,提问作者sagar suri




