现状
在我的应用程序中,我将保存为默认值
realm database
使用
insert
方法与
JsonReader
从下载的
json file
是的。
现在:一切正常,但是保存这么多数据只需要几分钟(2到5分钟)就可以完成parse-save操作。(我使用
OKHTTP
下载json文件-
.txt
-以及
InputStream
->
J读卡器
->
Gson
->
realm.insert
对于解析插入操作)
可能的改进思路
因为在我的应用程序逻辑中,此操作也可能在后台线程上完成,所以我在想是否可以执行如下操作:
-
从Internet异步下载数据
-
将数据保存到
new realm database
-
完成后,提示用户更新数据
-
从新数据库中提取一些表,并将它们放入带有批量delete insert的旧数据库中(我不在乎丢失这些表的旧数据,新数据总是正确的,用户不能编辑它们)。
实施过程中可能出现的问题
我对这个解决方案的开发很满意,但是在执行这样的重构操作之前,我有几个问题:
-
我可以执行保存操作吗
database2
在一个
background thread
让用户使用
UI
和
database1
在
main thread
否则两个数据库都将在
database2 insert
手术?
-
如果我当前的数据库使用
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,但我需要解析我的模型,因为我有一些日期字段必须用自定义类型适配器解析。