我正在尝试将大型json文件下载到Realm数据库中。 loadCarbay()
表现不错,但是checkTyres()
抛出了Realm.getDefaultInstance()
我已经在关闭实例上检查了所有领域代码-一切都很好。我检查了getLocalInstanceCount()
-崩溃前它返回0。我不明白我在做什么错?
void checkLoadData(){
final boolean hasCarbay = hasCarbay();
final boolean hasTyres = hasTyres();
if(!hasPersons()||!hasModels()||!hasDeparts()||!hasCarbay||!hasTyres){
if(checkWifi(this)){
if(!progressDialog.isShowing())progressDialog.show();
Thread t = new Thread(new Runnable() {
public void run() {
final String holding = ses.getString("holding_url");
final String curr = ses.getString("curBaseAAURL");
loadBase(holding,curr,"");
if(!hasPersons()) {
h.sendEmptyMessage(STATUS_LOADING_PERSONS_START);
loadTablePersons(LoginPageActivity.this, h, STATUS_LOADING_PERSONS_PROGRESS, STATUS_LOADING_PERSONS_END);
loadTopicsFromJson(LoginPageActivity.this);
}
if(!hasModels()){
h.sendEmptyMessage(STATUS_LOADING_MODELS_START);
loadAlfaModels(LoginPageActivity.this,h,STATUS_LOADING_ALFA_PROGRESS,STATUS_LOADING_ALFA_END);
}
if(!hasDeparts()){
h.sendEmptyMessage(STATUS_LOADING_WS_LINKS_START);
loadDepartments(LoginPageActivity.this);
h.sendEmptyMessage(STATUS_LOADING_WS_LINKS_END);
}
if(!hasCarbay){
h.sendEmptyMessage(STATUS_LOADING_CARBAY_START);
loadCarbayData(LoginPageActivity.this,h,STATUS_LOADING_CARBAY_END);
h.sendEmptyMessage(STATUS_LOADING_CARBAY_END);
}
if(!hasTyres){
h.sendEmptyMessage(STATUS_LOADING_TYRE_START);
loadTyres(LoginPageActivity.this,h,STATUS_LOADING_TYRE_END);
}
h.sendEmptyMessage(STATUS_LOADING_TYRE_END);
}
}
);
t.start();
}
}
}
private boolean hasCarbay(){
Realm realm = Realm.getDefaultInstance();
long count = realm.where(CarbayBrand.class)
.count();
boolean f = count>0;
realm.close();
return f;
}
private boolean hasTyres(){
boolean flag = false;
Realm realm = Realm.getDefaultInstance();
try{
long count = realm.where(Tyre.class).count();
if(count>0){
Tyre t = realm.where(Tyre.class).findFirst();
if(t!=null){
if(t.getUid()!=null && !t.getUid().isEmpty()){
flag = true;
}
}
}
Log.d("hasTyre","count="+count);
}catch (Exception e){
e.printStackTrace();
}finally {
realm.close();
}
return flag;
}
//loading data to realm
synchronized void loadCarbayData(Context context, Handler h, int LOADING_END){
GlobalParams globalParams = new GlobalParams(context);
final String url1 = "http://" + globalParams.storage_url + "/carbay/car_bay_data.txt";
final String url2 = "http://" + globalParams.storage_url + "/carbay/carbay_ref1.json";
final String url3 = "http://" + globalParams.storage_url + "/carbay/carbay_ref2.json";
final String url4 = "http://" + globalParams.storage_url + "/carbay/carbay_ref3.json";
//Log.d("JsonGet", "Realm closed! Realm instances="+Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()));
Realm realm = Realm.getDefaultInstance();
try{
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(TradeInCarbay.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayBrand.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayModels.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayModifications.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayDataLink.class);
}
});
// Insert multiple items using an InputStream
Log.d("JsonGet", "Старт загрузки справочника Карбей");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url1);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(TradeInCarbay.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Log.d("JsonGet", "Старт загрузки регистра Карбей ч1");
// Insert multiple items using an InputStream
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url2);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(CarbayBrand.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Log.d("JsonGet", "Старт загрузки регистра Карбей ч2");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url3);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(CarbayBrand.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Log.d("JsonGet", "Старт загрузки регистра Карбей ч3");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url4);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(CarbayBrand.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}catch (Exception e){
e.printStackTrace();
}
finally {
realm.close();
//Log.d("JsonGet", "Realm closed! Realm instances="+Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()));
}
Message msg;
msg = h.obtainMessage(LOADING_END, 0, 0);
h.sendMessage(msg);
}
synchronized void loadTyres(Context context, Handler h, int LOADING_END){
GlobalParams globalParams = new GlobalParams(context);
final String url1 = "http://" + globalParams.storage_url + "/get_tyres_v2.php";
Log.d("JsonGet", "Старт загрузки справочника шин");
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(Tyre.class);
}
});
// Insert multiple items using an InputStream
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url1);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(Tyre.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}catch (Exception e){
e.printStackTrace();
}
Message msg;
msg = h.obtainMessage(LOADING_END, 0, 0);
h.sendMessage(msg);
}
我的logcat错误消息
2019-07-12 15:05:09.347 11321-11362/com.lx2.crm E/REALM_JNI: jni: ThrowingException 5, mmap() failed: Out of memory size: 369098752 offset: 0 in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101, .
2019-07-12 15:05:09.350 11321-11362/com.lx2.crm E/REALM_JNI: Exception has been thrown: Unrecoverable error. mmap() failed: Out of memory size: 369098752 offset: 0 in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
2019-07-12 15:05:09.352 11321-11362/com.lx2.crm E/AndroidRuntime: FATAL EXCEPTION: Thread-10
Process: com.lx2.crm, PID: 11321
io.realm.exceptions.RealmError: Unrecoverable error. mmap() failed: Out of memory size: 369098752 offset: 0 in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:184)
at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:254)
at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:244)
at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:319)
at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:282)
at io.realm.Realm.getDefaultInstance(Realm.java:332)
at com.lx2.crm.LoginPageActivity.loadTyres(LoginPageActivity.java:1154)
at com.lx2.crm.LoginPageActivity$11.run(LoginPageActivity.java:1001)
at java.lang.Thread.run(Thread.java:764)
答案 0 :(得分:0)
Ilhat,欢迎使用StackOverflow。
loadTyres()的一个不同之处在于,它使用的是try-with-resources语句:
try(Realm realm = Realm.getDefaultInstance()) {
loadCarbay()不是:
Realm realm = Realm.getDefaultInstance();
try{
也许Realm与try-with-resource语句不兼容。
尝试让try
块之前的loadCarbay()获取领域实例,以查看是否可以解决问题。这只是一个猜测。
如果执行此操作,请记住还使用realm.close();
答案 1 :(得分:0)
我发现了为什么每次获得实例时Realm都崩溃的原因-设备中的内存不足。我正在将我的应用程序安装在内存较大的另一台设备上,并且一切正常。
答案 2 :(得分:0)
在异步任务未完成之前,似乎没有设置领域释放内存。这就是为什么即使我尝试分割文件加载时也出现内存不足错误的原因。我的解决方案是划分加载文件,并为每个文件执行异步任务。每个异步任务都从上一个任务中的回调开始。有点难看,但是可以用