2012-08-16 83 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

我的建議是重新定義你的結構是如何工作的。例如,獲取關於聯繫人的基本信息,顯示名稱和其他元數據是非常快速的。將它顯示在列表中或其他內容中,然後在選擇或查看聯繫人時加載其餘的信息。

這會加速很多。但是,如果您必須立即加載有關聯繫人的所有信息,那麼肯定會由於需要執行多少查詢而變得非常慢。

另一個建議是將它們顯示爲完成給用戶。這樣有一些進展,他們可以查看它。而不是隻是把一個對話框,說「加載等待」。

相關問題