2012-08-16 78 views
2

嗨我目前在做联系,如果我从接触* (电子邮件,电话号码和联系人姓名) *获取详细信息相关项目和它well.But的问题是,它需要很长的时间来获取联系方式(包括来自社交网站同步的1000多名联系人)包括。因此,我为此设置了一个Asynchronous Task,并且它的表现不错,但问题是由于很长时间才能完成提取过程,当我按后退按钮它在异步任务期间崩溃。我的问题不会崩溃为什么这个提取的联系人花费了大量的时间。有办法让contact更快。我的代码来获得接触的细节低于获取联系人详细信息花费大量的时间在android?

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("[email protected]+\\.[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; 
} 

回答

3

好吧,我想我终于看到了这个工作的最佳方式。在创建适配器之前,您应该创建一个自定义的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. 
    } 
} 
+0

好的建议,但你能告诉我一个自定义CursorAdapter的例子 – Ramz 2012-08-16 18:44:17

+0

当然。当我有一段时间的时候,我会编辑一个。 – Stuporman 2012-08-16 19:27:27

+0

okey谢谢,请尽快发布:) – Ramz 2012-08-16 19:41:17

0

我的建议是重新定义你的结构是如何工作的。例如,获取关于联系人的基本信息,显示名称和其他元数据是非常快速的。将它显示在列表中或其他内容中,然后在选择或查看联系人时加载其余的信息。

这会加速很多。但是,如果您必须立即加载有关联系人的所有信息,那么肯定会由于需要执行多少查询而变得非常慢。

另一个建议是将它们显示为完成给用户。这样有一些进展,他们可以查看它。而不是只是把一个对话框,说“加载等待”。

相关问题