Android - 将大 JSON 保存到 Realm OutOfMemoryException
Android - Save big JSON to Realm OutOfMemoryException
情况:
我的服务器 ( >= 50-100Mb ) 上有一个很大的 Json file
,其中包含我需要在我的应用程序中使用的所有客户的信息。
我必须将文件下载到我的应用程序中并将所有信息保存到我的 Realm
数据库中。 (此文件中有将近 200k 个对象)。
Customer.class
这是保存在此数组中的对象:
public class Customer extends RealmObject {
public Customer(){}
@PrimaryKey
private String ID;
private String FULL_NAME;
private String PHONE_NO;
private String CODICE_FISCALE;
private Date MODIFIED_ON;
//getters and setters
我的下载保存码:
这是一个AsyncTask
,我删除了所有无用的代码以便于查看
@Override
protected Void doInBackground(String... params) {
Realm realm = null;
newSha = null;
try {
realm = Realm.getDefaultInstance();
String url = "myurl";
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder().url(url)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
try {
String myHeader = response.header("Content-Disposition");
if (myHeader != null) {
int position = myHeader.indexOf("filename=");
position += "filename=".length();
newSha = myHeader.substring(position);
}
} catch (Exception ex) {
newSha = null;
}
if (responseBody == null) {
return null;
}
InputStream is = responseBody.byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
response.close();
responseBody.close();
is.close();
reader.close();
//switch because i have 20-30 cases, this is the big file which gives problems
switch (fileName) {
case "Customers": {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
Log.wtf("SYNC", "Customer - start delete");
realm.delete(Customer.class);
Log.wtf("SYNC", "Customer - end delete, start create"); //this line is reached
realm.createAllFromJson(Customer.class, sb.toString());
Log.wtf("SYNC", "Customer - end create"); //this line is never reached
setTitle(String.format("Completato! [%s]", title));
publishProgress(100, 1);
addSyncCompleted(false, null, null);
genericDbClass.setSHA(realm, new Customer(), newSha);
} catch (Exception error) {
newSha = null; //this error is never thrown
}
}
});
}
break;
问题:
realm.createAllFromJson
抛出一个 OutOfMemoryException
(不是真的抛出,应用程序刚刚关闭 没有触发捕获 并且没有任何错误。我只能在日志中看到一些异常记录为 Warn
W/art: Throwing OutOfMemoryError "Failed to allocate a 170348044 byte allocation with 16777216 free bytes and 162MB until OOM"
问题是如何将这么大的 Json 文件保存到 Realm 中。我之前也尝试过用 Gson 解析这个字符串,但没有成功。该文件的大小可能会随着时间的推移而增加,那么我该如何加快速度呢?
任何帮助将不胜感激,我已经坚持了一个星期。
Realm 有一个 createAllFromJson()
的流变体,它直接接受 InputStream
:https://realm.io/docs/java/3.7.1/api/io/realm/Realm.html#createAllFromJson-java.lang.Class-java.io.InputStream-
这还可以防止您 运行 内存不足。
情况:
我的服务器 ( >= 50-100Mb ) 上有一个很大的 Json file
,其中包含我需要在我的应用程序中使用的所有客户的信息。
我必须将文件下载到我的应用程序中并将所有信息保存到我的 Realm
数据库中。 (此文件中有将近 200k 个对象)。
Customer.class
这是保存在此数组中的对象:
public class Customer extends RealmObject {
public Customer(){}
@PrimaryKey
private String ID;
private String FULL_NAME;
private String PHONE_NO;
private String CODICE_FISCALE;
private Date MODIFIED_ON;
//getters and setters
我的下载保存码:
这是一个AsyncTask
,我删除了所有无用的代码以便于查看
@Override
protected Void doInBackground(String... params) {
Realm realm = null;
newSha = null;
try {
realm = Realm.getDefaultInstance();
String url = "myurl";
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder().url(url)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
try {
String myHeader = response.header("Content-Disposition");
if (myHeader != null) {
int position = myHeader.indexOf("filename=");
position += "filename=".length();
newSha = myHeader.substring(position);
}
} catch (Exception ex) {
newSha = null;
}
if (responseBody == null) {
return null;
}
InputStream is = responseBody.byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
response.close();
responseBody.close();
is.close();
reader.close();
//switch because i have 20-30 cases, this is the big file which gives problems
switch (fileName) {
case "Customers": {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
Log.wtf("SYNC", "Customer - start delete");
realm.delete(Customer.class);
Log.wtf("SYNC", "Customer - end delete, start create"); //this line is reached
realm.createAllFromJson(Customer.class, sb.toString());
Log.wtf("SYNC", "Customer - end create"); //this line is never reached
setTitle(String.format("Completato! [%s]", title));
publishProgress(100, 1);
addSyncCompleted(false, null, null);
genericDbClass.setSHA(realm, new Customer(), newSha);
} catch (Exception error) {
newSha = null; //this error is never thrown
}
}
});
}
break;
问题:
realm.createAllFromJson
抛出一个 OutOfMemoryException
(不是真的抛出,应用程序刚刚关闭 没有触发捕获 并且没有任何错误。我只能在日志中看到一些异常记录为 Warn
W/art: Throwing OutOfMemoryError "Failed to allocate a 170348044 byte allocation with 16777216 free bytes and 162MB until OOM"
问题是如何将这么大的 Json 文件保存到 Realm 中。我之前也尝试过用 Gson 解析这个字符串,但没有成功。该文件的大小可能会随着时间的推移而增加,那么我该如何加快速度呢?
任何帮助将不胜感激,我已经坚持了一个星期。
Realm 有一个 createAllFromJson()
的流变体,它直接接受 InputStream
:https://realm.io/docs/java/3.7.1/api/io/realm/Realm.html#createAllFromJson-java.lang.Class-java.io.InputStream-
这还可以防止您 运行 内存不足。