You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何改写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

火山引擎 最新活动