【问题标题】:Android - Best approach to parse huge (extra large) JSON file from assetsAndroid - 从资产中解析巨大(超大)JSON文件的最佳方法
【发布时间】:2022-01-31 02:01:41
【问题描述】:

我正在尝试从资产文件夹中解析一些巨大的 JSON 文件。我如何加载并添加到 RecyclerView。想知道解析这种大文件(大约 6MB)的最佳方法是什么,以及您是否知道可以帮助我处理这个的好 API。

【问题讨论】:

    标签: android json


    【解决方案1】:

    我建议您使用GSON lib。它的性能非常好。

    只需在你的 gradle 文件中添加这一行来导入 lib。

    compile 'com.google.code.gson:gson:2.2.4'
    

    如果您的 JSON 以“[”(假设是用户数组)开头,您可以像这样使用 GSON:

    public Set<User> getUsers(final Activity activity) {
    
        Set<User> usersList = new HashSet<>();
        String json = readFromAsset(activity, "myfile_with_array.json");
        Type listType = new TypeToken<HashSet<User>>() {}.getType();
        // convert json into a list of Users
        try {
            usersList = new Gson().fromJson(json, listType);
        }
        catch (Exception e) {
            // we never know :)
            Log.e("error parsing", e.toString());
        }
        return usersList;
    }
    
    /**
     * Read file from asset directory
     * @param act current activity
     * @param fileName file to read
     * @return content of the file, string format
     */
    private  String readFromAsset(final Activity act, final String fileName)
    {
        String text = "";
        try {
            InputStream is = act.getAssets().open(fileName);
    
            int size = is.available();
    
            // Read the entire asset into a local byte buffer.
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            text = new String(buffer, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return text;
    }
    

    这将返回一组用户。

    如果你的 JSON 以“{”开头,那么可以映射到一个对象(比如说用户对象),你可以这样使用它:

    public User getUser(final Activity activity) {
    
            User user = null;
            String json = readFromAsset(activity, "myfile_with_object.json");
            try {
            // convert json in an User object
                user = new Gson.fromJson(json, User.class)
            }
            catch (Exception e) {
                // we never know :)
                Log.e("error parsing", e.toString());
            }
            return user;
        }
    

    希望这会有所帮助!

    【讨论】:

    • 非常感谢它对我的帮助,抱歉回复晚了:)
    • 同理,如何读取超过300MB的文件。我收到 OutofMemory(OOM) 错误。
    • @Vasu 您找到解决方案了吗?实际上我的 json 文件也是 380 MB,我是 Android 开发新手。
    【解决方案2】:

    尝试使用google的GSON

    Gson 提供简单的 toJson() 和 fromJson() 方法将 Java 对象转换为 JSON,反之亦然

    它只需要代表你的对象的类(你甚至可以从jsonhere在线生成)然后调用:

    MyObject obj = new Gson.fromJson(jsonString,MyObject.class)
    

    【讨论】:

      【解决方案3】:

      没有有效的方法来加载一个大的 JSON,除了将它全部读取并将其放入 JSONObject 中,除非结构是静态的,并且您可以为其创建解析器以逐行读取它。

      不过,6MB 并不是那么大。

      根据应用程序和内存需求,在 RecyclerView 中加载尽可能多的数据项,然后根据需要添加更多数据项。此外,您可以加载 JSON,然后在不再需要时将其清空。

      字符串到 JSON 对象:

      JsonObject json = new JsonObject(string);
      

      【讨论】:

        【解决方案4】:

        我有同样的问题,我有一个 60MB 的 json 文件,所以最好的方法是将你的 json 数据转换成你可以轻松访问的 SQLite 数据库。

        1. 使用此站点将您的 JSON 文件转换为 SQLITE,它适用于文件 https://konbert.com/convert
          (所以如果您需要转换更大的文件,请使用这些methods

        2. 转换数据后,您会看到文件大小减小了,我的从 60MB 变为 9MB

        3. 然后将你的DB放到你的assets文件夹中,并使用ROOM DB访问数据库你可以一步步查看这个教程https://developer.android.com/codelabs/android-room-with-a-view-kotlin#0或者在Youtube上看一些视频

        4. 为数据库创建所有类后,当您通过“databaseBuilder”创建数据库时,只需对数据库使用 createFromAsset() 方法即可。

           abstract class CityWeatherDatabase : RoomDatabase() {
          
                abstract val dao: CityWeatherDao
          
                companion object {
          
                    @Volatile
                    private var INSTANCE: CityWeatherDatabase? = null
          
                    fun getInstance(context: Context): CityWeatherDatabase {
                        synchronized(this) {
                            return INSTANCE ?: Room.databaseBuilder(
                                context.applicationContext,
                                CityWeatherDatabase::class.java,
                                "weather"
                            ).createFromAsset("database/weather.db")
                             .build().also {
                                INSTANCE = it
                            }
                        }
                    }
                }
           }
          

        如果您在模块文件中使用 Hilt 进行依赖注入

            @Provides
            @Singleton
            fun provideCityWeatherDatabase(app: Application): CityWeatherDatabase {
                return Room.databaseBuilder(
                    app, CityWeatherDatabase::class.java, "weather"
                ).createFromAsset("database/weather.db") 
                    .build()
            }
        

        【讨论】:

          猜你喜欢
          • 2020-06-15
          • 2015-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多