关于电话簿中的联系人列表的内存泄漏问题

时间:2013-09-04 16:30:30

标签: android contactscontract

每次点击标签时,我都会从手机上加载联系人列表。 它在第一次触摸时工作正常,但它从第二次引起内存问题。 我应该如何防止这个问题?

这是代码。

String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
            + " COLLATE LOCALIZED ASC";
try {
        contactsCursor= getContentResolver()
        .query(uri, null, null, null,  sortOrder);

        //Log.i("The first one", "" + contactsCursor.getCount());
        if(contactsCursor.getCount()>0){
            if(contactsCursor.moveToFirst()){
                while (contactsCursor.moveToNext()) {

                    String hasPhoneNumber = contactsCursor.getString(contactsCursor
                            .getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER));
                    int contTypeInt=0;
                    String contactType="";
                    ArrayList<String> phoneNumberList= new ArrayList<String>();
                    if (Integer.parseInt(hasPhoneNumber) > 0) {

                        String id = contactsCursor.getString(contactsCursor
                                .getColumnIndexOrThrow(ContactsContract.Contacts._ID));

                        Cursor phones = getContentResolver().query(
                                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id, null, null);
                        String phoneNumber = null;
                        if(phones!=null && phones.getCount()>0){
                            while (phones.moveToNext()) {
                                int type= phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                                if (type == Phone.TYPE_MOBILE){
                                    phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                                    phoneNumberList.add(phoneNumber);
                                }
                            }
                            contTypeInt++;
                            phones.close();
                            phones = null;
                        }
                    }

                    String id = contactsCursor.getString(contactsCursor
                            .getColumnIndexOrThrow(ContactsContract.Contacts._ID));
                    String name = contactsCursor.getString(contactsCursor
                            .getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
                    Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,null,
                            ContactsContract.CommonDataKinds.Email.CONTACT_ID+ " = " + id, null, null);
                    ArrayList<String> emailAddressList= new ArrayList<String>();
                    if(emails!=null && emails.getCount()>0){
                        while (emails.moveToNext()) 
                           {
                               // This would allow you get several email addresses
                               String emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                               if(strEmails.equals("")){
                                   strEmails= emailAddress;
                               }else{
                                   strEmails= strEmails+","+emailAddress;
                               }
                               Log.v(name+"==>", emailAddress);
                               if ((!emailAddress.equalsIgnoreCase(""))&&(emailAddress.contains("@"))) 
                               {   
                                Log.d("email", emailAddress);
                                   emailAddressList.add(emailAddress);
                               }
                           }
                        emails.close();
                        emails = null;
                    }

                    if(emailAddressList.size()>0){
                        //primaryEmailList.add(emailAddressList.get(0));
                        contTypeInt++;
                    }
                    if(contTypeInt==0){
                        contactType="";
                    }else if(contTypeInt==2){
                        contactType= "both";
                    }else if(contTypeInt==1){
                        if(emailAddressList.size()>0){
                            contactType="email";
                        }else{
                            contactType="phone";
                        }
                    }
                    Log.d(name+" conatctType", contactType);
                    if(name==null){
                        name="";
                    }

                    String []tempArr= name.split(" ");
                    for(int i=0;i<tempArr.length;i++){
                        if(tempArr[i].length()>1){
                            tempArr[i]= tempArr[i].substring(0, 1).toUpperCase() + tempArr[i].substring(1);
                        }
                    }
                    String nameTmp="";
                    for(int i=0;i<tempArr.length;i++){
                        if(nameTmp.equals("")){
                            nameTmp= tempArr[i];
                        }else{
                            nameTmp= nameTmp+" "+tempArr[i];
                        }

                    }
                    Constants.contactsList.add(new ContactsData(id, nameTmp, contactType, phoneNumberList, emailAddressList));
                    phoneNumberList = null;
                    emailAddressList = null;
                    tempArr = null;
                }
            }
        }
        contactsCursor.close();
        contactsCursor = null;
        }
        catch (Exception e) {

        }

有人帮我吗? 提前致谢

2 个答案:

答案 0 :(得分:1)

您应该使用Content Provider而不是光标。内容提供程序专门设计用于避免游标出现此类问题。

Here is an example

基本上,您应该一次查询这些数据。你一次要查询一下。这可能会导致SQLite出现问题,您应该重新设计代码。

答案 1 :(得分:0)

您的错误可能来自于未检查是否已创建加载联系人的此片段。为此,您需要检查传递给Fragment中onCreate()方法的Bundle是否为空。如果是第一次创建Fragment,则只应加载联系人。例如:

public void onCreate (Bundle savedInstanceState) {

    if(savedInstanceState == null) {
        // load the contacts
    }
}

请注意,这在任何片段中都很重要,因为每次布局从纵向更改为横向或反之时,都会重新创建片段。