【问题标题】:Fetching Contact detail Take A lot of time in android?获取联系方式在 android 中花费大量时间?
【发布时间】:2012-08-16 16:37:17
【问题描述】:

您好,目前正在做一个与联系人相关的项目,我正在从联系人那里获取详细信息*(电子邮件、号码和联系人姓名)*,它做得很好。但是问题是获取联系人详细信息需要很长时间(1000 多个联系人,包括从社交网站同步的联系人)。所以我为此设置了Asynchronous Task,效果很好但问题是由于完成获取过程的时间很长,当我按下后退按钮时它在异步任务期间崩溃。我的问题没有崩溃为什么这个获取联系人需要很多时间。有没有办法得到@ 987654322@ 更快。我获取联系方式的代码如下所示

public void readContact() {
    contactname = new ArrayList<String>();
    contactnumber = new ArrayList<String>();
    companyname_one = new ArrayList<String>();
    contactemail = new ArrayList<String>();
    people = getContentResolver().query(
            ContactsContract.Contacts.CONTENT_URI, null, null, null,
            PhoneLookup.DISPLAY_NAME);

    while (people.moveToNext()) {
        int nameFieldColumnIndex = people
                .getColumnIndex(PhoneLookup.DISPLAY_NAME);
        String contact = people.getString(nameFieldColumnIndex);
        if (contact == null) {
            contactname.add("No contact Set");
        } else {

            contactname.add(contact);

        }

        String szId = people.getString(people
                .getColumnIndexOrThrow(ContactsContract.Contacts._ID));

        cursor_one = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                null,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "='"
                        + szId + "'", null, null);
        if (cursor_one.moveToNext()) {
            String number = cursor_one.getString(cursor_one
                    .getColumnIndex(Phone.NUMBER));
            contactnumber.add(number);
            cursor_one.close();

        } else {
            contactnumber.add("no number");
            cursor_one.close();

        }

        emails_value = getContentResolver().query(
                Email.CONTENT_URI,
                null,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "='"
                        + szId + "'", null, null);

        if (emails_value.moveToNext()) {
            email_sorting = emails_value.getString(emails_value
                    .getColumnIndex(Email.DATA));
            checkAll();

        } else {

            contactemail.add("no email");
            emails_value.close();

        }

    }

    people.close();


    System.out.println("noz " + contactnumber);
    System.out.println("name" + contactname);
    System.out.println("email" + contactemail);
    System.out.println("noz size " + contactnumber.size());
    System.out.println("name size " + contactname.size());
    System.out.println("contactemail size " + contactemail.size());



}

checkAll() 方法是电子邮件的模式匹配,如下所示

    public boolean checkAll() {

    boolean chkAll = true;
    Pattern p1 = Pattern.compile(".+@.+\\.[a-z]+");
    Matcher m1 = p1.matcher(email_sorting.trim());

    if (!m1.matches()) {

        contactemail.add("no email");
        contactemail_sort.add("no email");
        emails_value.close();
        chkAll = false;


    } else {

        contactemail.add(email_sorting);
        contactemail_sort.add(email_sorting);
        emails_value.close();
        chkAll = true;
    }

    return chkAll;
}

【问题讨论】:

    标签: android database cursor android-contentprovider


    【解决方案1】:

    好的,我想我终于看到了最好的方法。与其在创建适配器之前提取所有联系信息,不如创建一个自定义 CursorAdapter 接受 people 光标并使用在后台线程上执行的 cursor_one 查询填充自定义视图。这应该利用 ListView 的自然延迟加载,让这项工作如您所愿。

    如果您至少使用 Android 3.0,则可以使用 Loaders 而不是使用 AsyncTask。

    我找到了一个自定义光标适配器here 的示例,这是我用来制作示例的。可能有更好的方法在代码中实现这一点,但这至少向您展示了要覆盖哪些方法以及在其中放入什么。

    public class ContactListCursorAdapter extends SimpleCursorAdapter {
    
        private Context context;
    
        private int layout;
    
        public ContactListCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
            super(context, layout, c, from, to);
            this.context = context;
            this.layout = layout;
        }
    
        // Used to populate new list items
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
    
            Cursor c = getCursor();
    
            final LayoutInflater inflater = LayoutInflater.from(context);
            View v = inflater.inflate(layout, parent, false);
    
            int nameCol = c.getColumnIndex(People.NAME);
    
            String name = c.getString(nameCol);
    
            /**
             * Next set the name of the entry.
             */     
            TextView name_text = (TextView) v.findViewById(R.id.name_entry);
            if (name_text != null) {
                name_text.setText(name);
            }
    
            getDeatils(v,c);
    
            return v;
        }
    
        // Used to bind a new item from the adapter to an existing view
        @Override
        public void bindView(View v, Context context, Cursor c) {
    
            int nameCol = c.getColumnIndex(People.NAME);
    
            String name = c.getString(nameCol);
    
            /**
             * Next set the name of the entry.
             */     
            TextView name_text = (TextView) v.findViewById(R.id.name_entry);
            if (name_text != null) {
                name_text.setText(name);
            }
    
            getDetails(v,c);
        }
    
        private void populateDetails(View v, Cursor c) {
           // Start your AsyncTask or Loader to get the details.
           // Be sure to populate the view with the results in the
           // appropriate completion callback.
        }
    }
    

    【讨论】:

    • 好建议,但你能给我看一个自定义 CursorAdapter 的例子
    • 是的,我认为它减少了时间,谢谢:)
    【解决方案2】:

    我的建议是重新定义您的结构的工作方式。例如,获取联系人的基本信息、显示名称和其他元数据真的很快。在列表或其他内容中显示它,然后当他们选择或查看联系人时,然后加载其余信息。

    这将大大加快速度。但是,如果您必须一次加载有关联系人的所有内容,那么是的,由于您需要执行多少查询,所以速度会非常慢。

    另一个建议是向用户显示它们已完成。这样就有一些进展,他们可以查看。而不是仅仅放置一个显示“加载等待”的对话框。

    【讨论】:

      猜你喜欢
      • 2020-05-06
      • 1970-01-01
      • 2018-01-10
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 2023-03-11
      • 1970-01-01
      相关资源
      最近更新 更多