Android 将新数据保存到另一个领域数据库并替换当前 现状
在我的应用程序中,我正在使用Android 将新数据保存到另一个领域数据库并替换当前 现状,android,realm,Android,Realm,在我的应用程序中,我正在使用insert方法,使用从下载的json文件中实例化的JsonReader将大约100Mb的数据保存到默认的realm数据库中 现在:一切正常,但是保存那么多数据只需要几分钟(2到5分钟)就可以完成解析保存操作。(我使用OKHTTP下载json文件-.txt-和InputStream->JsonReader->Gson->realm.insert用于解析插入操作) 可能的改进想法 由于在我的应用程序逻辑中,此操作也可能在后台线程上完成,因此我想知道是否可以执行如下操作:
insert
方法,使用从下载的json文件中实例化的JsonReader
将大约100Mb的数据保存到默认的realm数据库中
现在:一切正常,但是保存那么多数据只需要几分钟(2到5分钟)就可以完成解析保存操作。(我使用OKHTTP
下载json文件-.txt
-和InputStream
->JsonReader
->Gson
->realm.insert
用于解析插入操作)
可能的改进想法
由于在我的应用程序逻辑中,此操作也可能在后台线程上完成,因此我想知道是否可以执行如下操作:
从internet异步下载数据
将数据保存到新领域数据库中
完成后,提示用户更新数据
从新数据库中获取一些表,并通过批量删除插入将它们放入旧数据库中(我不在乎丢失这些表的旧数据,新表总是正确的,用户无法编辑它们)
这一执行可能存在的问题
我对这个解决方案的开发很满意,但在执行这样的重构操作之前,我有几个问题:
我是否可以在后台线程中执行对数据库2
的保存操作,并让用户在主线程上使用UI
和database1
,或者在database2 insert
操作期间锁定两个数据库
如果我当前的数据库使用默认配置
,我是否可以使用自定义配置
创建另一个域数据库,只传递一个不同的数据库名称
这就是我想为最终更换操作所做的(obv它只是一个示例,只是从中提取概念):
关于这一点:
- 这是一个合理的解决方案吗李>
- 这个解决方案会比使用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");
在这两种情况下,插入操作都相当长
问题可能是Gson,但我需要解析我的模型,因为我有一些日期字段必须用自定义typeAdapter解析。它会崩溃,说“你需要在写事务中”,因为executeTransaction
缺失。@EpicPandaForce是的,我知道,这只是为了解释我的想法而写的一句话:)我的目标是想知道这个过程是否可行,以及这是否值得付出努力。我更好奇的是,为什么最初需要2-5分钟来构建。它是在一次交易中完成的吗?方法分析说明了什么?@EpicPandaForce我添加了下载任务的相关代码。它当然是可以优化的,但我真的不知道如何优化
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");
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");