我已经将Realm作为我的数据库实现,并且在我的应用程序中,我在电话联系人上运行服务以检查我的电话簿中的任何更改。 该服务适用于3到4次更改,然后应用程序在我的logcat中崩溃并出现此错误。
无法恢复的错误。 mremap():失败:io_realm_internal_SharedGroup.cpp第188行内存不足
这是我的代码:
public static void refreshingContactsDB()
{
createCountryDetailsArrayModel();
TelephonyManager tm = (TelephonyManager) ApplicationController.getInstance()
.getSystemService(Context.TELEPHONY_SERVICE);
String simCountryISO = tm.getSimCountryIso();
for (int i = 0; i < countryDetailsList.size(); i++) {
if (simCountryISO.equalsIgnoreCase(countryDetailsList.get(i)
.getCode())) {
dialCodePrefix = countryDetailsList.get(i).getDial_code();
}
}
AppPreferenceManager.getInstance().setContactUpdate(false);
Logger.debug("Contact Update Refreshing Contact Started -->");
Thread background = new Thread(new Runnable() {
public void run() {
Realm realmRefresh = Realm.getInstance(ApplicationController.getInstance());
ContentResolver cr = ApplicationController.getInstance()
.getContentResolver();
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);
String duplicateName = "";
String duplicatePhone = "";
if (phones.getCount() > 0) {
final int nameIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
final int numberIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
while (phones.moveToNext()) {
String name = phones.getString(nameIndex);
String phoneNo = phones.getString(numberIndex);
if (phoneNo != null && !phoneNo.isEmpty()) {
phoneNo = phoneNo.replace(" ", "");
phoneNo = phoneNo.replace("(", "");
phoneNo = phoneNo.replace(")", "");
phoneNo = phoneNo.replace("-", "");
phoneNo = phoneNo.replace("\u00a0", "");
phoneNo = phoneNo.replace("\u202c", "");
phoneNo = phoneNo.replace("\u2011", "");
phoneNo = phoneNo.replace("\u202a", "");
phoneNo = phoneNo.replace("*", "");
phoneNo = phoneNo.replace("#", "");
if (phoneNo.length() >= 5) {
if (name.equalsIgnoreCase(duplicateName) && phoneNo.equalsIgnoreCase(duplicatePhone)) {
continue;
}
duplicateName = name;
duplicatePhone = phoneNo;
String formattedPhoneNumber;
formattedPhoneNumber = parseNumber(phoneNo);
// List<LocalContactDb> getContactsList = Select
// .from(LocalContactDb.class)
// .where(Condition.prop("PHONE").eq(
// formattedPhoneNumber))
// .list();
RealmResults<R_LocalContactDB> realmResults = realmRefresh.where(R_LocalContactDB.class).equalTo("phone", formattedPhoneNumber).findAll();
Logger.debug("Size: " + realmResults.size());
RealmResults<R_LocalContactDB> query = realmRefresh.where(R_LocalContactDB.class).findAll();
R_LocalContactDB rContacts = new R_LocalContactDB(null, null, false, 0);
if (realmResults.size() == 0) {
realmRefresh.beginTransaction();
R_LocalContactDB rCont = realmRefresh.copyToRealm(rContacts);
rCont.setName(name);
rCont.setPhone(formattedPhoneNumber);
rCont.setStatus(0);
rCont.setMatchedWithRecent(true);
Logger.debug("New Size: " + query.size());
realmRefresh.commitTransaction();
Logger.debug("Contact Update " + name
+ " saved");
} else {
realmRefresh.beginTransaction();
if (!name.equalsIgnoreCase(realmResults.get(0).getName())) {
realmResults.get(0).setName(name);
}
realmResults.get(0).setMatchedWithRecent(true);
// realmResults.get(0);
Logger.debug("New Size Else Condition: " + query.size());
realmRefresh.commitTransaction();
realmRefresh.close();
}
}
}
}
ContactsSyncService.contactUpdated= false ;
phones.close();
}
deleteExtraContacts();
getNumbersFromDBAndUpdate();
}
});
background.start();
}
我已经阅读了这篇文章,但似乎无法从文档中完全理解它:
请注意,写入会相互阻塞,如果正在进行其他写入操作,则会阻止它们创建的线程。如果您正在从UI线程执行写操作,同时还从后台线程执行写操作,则会导致ANR错误。为了避免这种情况,首先在事务外部首先在内存中创建对象,并且只在事务中执行一个简单的Realm.copyToRealm(),这会将阻塞时间保持在最低限度。
答案 0 :(得分:2)
您很可能内存不足,因为您在Realm.getInstance()
- 主题中调用了parseContactstoContactsDB
而没有再次关闭它。
因为每次调用该方法时都在创建一个新线程,所以每次有效地打开一个全新的Realm会占用非常重要的内存。
在退出线程之前调用realm.close()
应该再次释放这些资源并防止内存不足。