代码之家  ›  专栏  ›  技术社区  ›  Pier Giorgio Misley

将新数据保存到另一个领域数据库并替换当前

  •  0
  • Pier Giorgio Misley  · 技术社区  · 6 年前

    现状

    在我的应用程序中,我将保存为默认值 realm database 使用 insert 方法与 JsonReader 从下载的 json file 是的。

    现在:一切正常,但是保存这么多数据只需要几分钟(2到5分钟)就可以完成parse-save操作。(我使用 OKHTTP 下载json文件- .txt -以及 InputStream -> J读卡器 -> Gson -> realm.insert 对于解析插入操作)

    可能的改进思路

    因为在我的应用程序逻辑中,此操作也可能在后台线程上完成,所以我在想是否可以执行如下操作:

    1. 从Internet异步下载数据
    2. 将数据保存到 new realm database
    3. 完成后,提示用户更新数据
    4. 从新数据库中提取一些表,并将它们放入带有批量delete insert的旧数据库中(我不在乎丢失这些表的旧数据,新数据总是正确的,用户不能编辑它们)。

    实施过程中可能出现的问题

    我对这个解决方案的开发很满意,但是在执行这样的重构操作之前,我有几个问题:

    1. 我可以执行保存操作吗 database2 在一个 background thread 让用户使用 UI database1 main thread 否则两个数据库都将在 database2 insert 手术?
    2. 如果我当前的数据库使用 default configurations ,我可以用 custom configurations 只是传递一个不同的数据库名称?

    这是我想做的最后一个替换操作(obv这只是一个样本,只是把这个概念拿出来):

    Realm oldRealm = Realm.getDefaultInstance();
    Realm newRealm = Realm.getInstance(secondConfig);
    
    //assume it's inside a transaction
    oldRealm.delete(mytable.class);
    oldRealm.insert(newRealm.where(myTable.class).findAll());
    

    关于这个:

    • 这是一个合理的解决方案吗?
    • 这个解决方案是否比使用jsonreader下载和插入更快?
    • 有更好的办法吗?

    谢谢大家,很抱歉发了那么长的邮件/英语不好

    编辑

    我的下载保存代码 (装配。我同步下载了+30个文件并将它们保存到我的数据库中。最大的一个大约为70MB,写事务需要很多时间):

    我删除了无用的代码,只留下了相关的部分。占用所有时间的行是插入数据库。 我也试过不使用GSON但我需要它

    //i'm inside an AsyncTask here
    @Override
    protected Void doInBackground(String... params) {
        Realm realm = null;
        try {
            realm = Realm.getDefaultInstance();
    
            String url = myDownloadFileURL;
    
            //here I download my files with OkHttp
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(600, TimeUnit.SECONDS)
                    .readTimeout(600, TimeUnit.SECONDS)
                    .retryOnConnectionFailure(true)
                    .build();
    
            Request request = new Request.Builder().url(url)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Connection", "close")
                    .build();
            Response response = client.newCall(request).execute();
    
            ResponseBody responseBody = response.body();
    
            if (responseBody == null) {
                return null;
            }
    
            // I save all my files into the internal storage because otherwise they will make the connection timeout
            File extStorageDirectory = Environment.getExternalStorageDirectory();
            File myFolder = new File(extStorageDirectory, BuildConfig.FLAVOR);
            myFolder.mkdirs();
            final File file = new File(myFolder, fileName + ".txt");
            FileOutputStream outputStream = new FileOutputStream(file);
            InputStream is = responseBody.byteStream();
            byte[] buffer = new byte[4096]; //Buffer size, Usually 1024-4096
            int len;
            while ((len = is.read(buffer, 0, buffer.length)) > 0) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.flush();
            outputStream.close();
    
            responseBody.close();
            client.connectionPool().evictAll();
    
            //here I analyze my downloaded data and I save them to realm.
            //I put only one case, they are all the same :)
            switch (fileName) {
                case "Cities": {
                    realm.executeTransaction(new Realm.Transaction() {
                        @Override
                        public void execute(Realm realm) {
                            try {
                               // {0} --> REFER BELOW
                            } catch (Exception error) {
                                //removed not useful code
                            }
                        }
                    });
                    break;
                }
                default:
                    break;
            }
            response.close();
    
        } catch (IOException error) {
            //removed not useful code
        } finally {
            if (realm != null) {
                realm.close();
            }
        }
        return null;
    }
    
    @Override
    protected void onPostExecute(Void v) {
        //removed not useful code
    }
    

    {0}-->请参阅下面的内容

    对于那部分代码(慢的代码),我尝试了很多方法。这两个是性能和无错误抛出的最佳选择:

    1)使用解析列表

    Log.wtf("SYNC", "City - start delete");
    realm.delete(City.class);
    Log.wtf("SYNC", "City - end delete, start create");
    BufferedReader reader = new BufferedReader(new FileReader(file));
    realm.insert((List<City>) gson.fromJson(reader, new TypeToken<List<City>>(){}.getType()));
    Log.wtf("SYNC", "City - end create");
    

    2)使用jsonreader

    Log.wtf("SYNC", "City - start delete");
    realm.delete(Meter.class);
    Log.wtf("SYNC", "City - end delete, start create");
    InputStream is = new FileInputStream(file);
    JsonReader jReader = new JsonReader(new InputStreamReader(is));
    jReader.beginArray();
    while (jReader.hasNext()) {
        realm.insert((City) gson.fromJson(jReader, City.class));
    }
    jReader.endArray();
    jReader.close();
    Log.wtf("SYNC", "City - end create");
    

    在这两种情况下,插入操作都很长。

    问题可能是gson,但我需要解析我的模型,因为我有一些日期字段必须用自定义类型适配器解析。

    0 回复  |  直到 6 年前