嗨我知道我之前发过同样的问题,但似乎无法找到正确的方法。 如果联系人有任何更改,这是我的类,由服务调用。值得注意的是,该服务不断调用,可能导致内存泄漏,不确定。
以下是服务类的代码:
public class ContactsSyncService extends Service {
public static int count =0;
int k = 0;
public static boolean contactUpdated = false;
ContentObserver mObserver;
public Context contextService = ContactsSyncService.this;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
k++;
if (!contactUpdated)
{
contactUpdated = true;
Logger.debug("Contact Update to start -->");
FetchLocalContacts.refreshingContactsDB();
}
}
};
getContentResolver().registerContentObserver(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, true, mObserver);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
getContentResolver().unregisterContentObserver(mObserver);
}
}
这是导致内存泄漏的类:
public static void parseContactstoContactsDB()
{
Thread background = new Thread(new Runnable()
{
public void run()
{
Realm realmFetchFirstTime = 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);
realmFetchFirstTime.beginTransaction();
R_LocalContactDB rContacts = realmFetchFirstTime.createObject(R_LocalContactDB.class);
rContacts.setName(name);
rContacts.setPhone(formattedPhoneNumber);
realmFetchFirstTime.commitTransaction();
Logger.debug("Formatted Contacts --> Name: "
+ name
+ " -- Phone No: "
+ formattedPhoneNumber);
}
}
}
phones.close();
}
realmFetchFirstTime.close();
// getNumbersFromDBAndUpdate();
}
});
background.start();
}
public static void getNumbersFromDBAndUpdate()
{
Realm realmServer = Realm.getInstance(ApplicationController.getInstance());
RealmResults<R_LocalContactDB> query = realmServer.where(R_LocalContactDB.class).findAll();
Logger.debug("Contact Update updating to server -->");
for (int i = 0; i < query.size(); i++)
{
phoneNumberJsonArray.put(query.get(i).getPhone());
}
try
{
uploadContactJsonBody.put("phone_numbers", phoneNumberJsonArray);
Logger.debug("LocalContacts RequestJson ---> "
+ uploadContactJsonBody.toString());
AppPreferenceManager.getInstance().setContactPref(1);
UploadLocalContactsToServerAsynTask test = new UploadLocalContactsToServerAsynTask(
uploadContactJsonBody.toString(),
new LocalContactsSyncCallBack()
{
@Override
public void didFinishProfileSync(boolean bool,
String result) {
Logger.debug("Is ContactUpdated FetchContacts --> "
+ bool);
setMatchedStatusToFalse();
AppPreferenceManager.getInstance().setContactUpdate(bool);
Intent roomIntent = new Intent();
roomIntent
.setAction("com.advisualinc.echo.fetch.local_contacts");
ApplicationController.getInstance().sendBroadcast(roomIntent);
}
});
test.execute();
}
catch (JSONException e)
{
e.printStackTrace();
}
realmServer.close();
}
public static void refreshingContactsDB()
{
Thread background = new Thread(new Runnable()
{
public void run()
{
realmFresh = Realm.getInstance(ApplicationController.getInstance());
createCountryDetailsArrayModel();
R_LocalContactDB rCont;
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 -->");
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);
R_LocalContactDB realmResults = realmFresh.where(R_LocalContactDB.class).equalTo("phone", formattedPhoneNumber).findFirst();
Logger.debug("Size: " + realmResults);
R_LocalContactDB rContacts = new R_LocalContactDB(null, null, false, 0);
if (realmResults == null)
{
i++;
realmFresh.beginTransaction();
rCont = realmFresh.copyToRealm(rContacts);
rCont.setName(name);
rCont.setPhone(formattedPhoneNumber);
rCont.setStatus(0);
rCont.setMatchedWithRecent(true);
// Logger.debug("New Size: " + query.size());
realmFresh.commitTransaction();
}
else if( realmResults.isValid())
{
realmFresh.beginTransaction();
if (!name.equalsIgnoreCase(realmResults.getName()))
{
realmResults.setName(name);
}
realmResults.setMatchedWithRecent(true);
// Logger.debug("New Size Else Condition: " + query.size());
realmFresh.commitTransaction();
}
}
}
}
ContactsSyncService.contactUpdated = false;
realmFresh.close();
}
deleteExtraContacts();
getNumbersFromDBAndUpdate();
}
});
background.start();
}
private static void deleteExtraContacts()
{
Realm realmDelete = Realm.getInstance(ApplicationController.getInstance());
RealmResults<R_LocalContactDB> query = realmDelete.where(R_LocalContactDB.class).equalTo("matchedWithRecent", false).findAll();
realmDelete.beginTransaction();
for (int i = 0; i < query.size(); i++)
{
try
{
query.remove(i);
}
catch (ArrayIndexOutOfBoundsException e)
{
Logger.debug("Array Out of Bounds");
}
}
realmDelete.commitTransaction();
realmDelete.close();
}
private static void setMatchedStatusToFalse()
{
Realm realmSetMatch = Realm.getInstance(ApplicationController.getInstance());
realmSetMatch.beginTransaction();
RealmResults<R_LocalContactDB> query = realmSetMatch.where(R_LocalContactDB.class).findAll();
for (int i = 0; i < query.size(); i++)
{
R_LocalContactDB contactDb = query.get(i);
contactDb.setMatchedWithRecent(false);
}
realmSetMatch.commitTransaction();
realmSetMatch.close();
}
答案 0 :(得分:0)
你的realmFresh.close()
由if (phones.getCount() > 0)
保护,所以如果你的getCount() == 0
你不会关闭王国并泄漏内存。您是否尝试将close()方法移到if语句之外?