2011-09-04 62 views
2

在我的應用程序中有5個調音臺與手機中的聯繫人填充。我使用下面的代碼來填充與聯繫人的數組,然後用數組的項目填充旋轉器(這裏只有1個微調器)。Android加載聯繫人太慢

當用戶打開該應用程序時,將會填充旋鈕,以便用戶可以爲每個旋鈕選擇一個名稱。 事情是,當用戶打開應用程序時,需要花費大約3秒的時間用旋鈕加載佈局。在玩完代碼之後,我發現無論應用程序中是否有可能出現spinners,問題的根源在於代碼與聯繫人一起填充數組。 我也發現了速度慢的原因:我在我的兄弟手機上運行了應用程序,並在那裏打開應該儘可能快。他在手機中只有30個聯繫人,而我有大約500個,其中大多數都是Facebook聯繫人。那麼我該如何幫助這種情況呢?

這是問題,與spinners的數量無關。在過多次接觸的情況下,這得慢:

contactName = null; 
     final Context context = getApplicationContext(); 

     ContentResolver cr = getContentResolver(); 
     Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); 
     if (cur.getCount() > 0) 
     { 
      while (cur.moveToNext()) { 
      String idc = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); 
      String namec = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 

      if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) 
      { 
       Cursor pCur = cr.query(
       ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 
       ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{idc}, null); 
       while (pCur.moveToNext()) { 
        contactName = pCur.getString(pCur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 

        myArr.add(contactName); 
       } 
       pCur.close(); 
       } 

      } 
     } 

     myArr.add(""); 
     Collections.sort(myArr); 

這是我如何填充每個微調(並使其顯示先前選擇的名稱):

 Spinner sp1 = (Spinner) findViewById(R.id.Spinner01); 
     ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, myArr); 
     sp1.setAdapter(adapter1); 
     sp1.setOnItemSelectedListener(new MyOnItemSelectedListener1()); 


     mprefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); 
     val1 = mprefs.getString("value1", "No name"); 
     if (!val1.equals("No name")) 
     { 
      for (int i=0; i<myArr.size(); i++) 
      { 
       if (val1.equals(myArr.get(i))) 
       { 
        num = i; 
       } 
      } 
      sp1.setSelection(num); 
     } 
     else 
     { 
      sp1.setSelection(0); 
     } 

解決方案基於這樣的想法Jesse van Assen:

原來問題是第二個查詢。我刪除了這一個創造了「投影」變量我所需要的列:

final String[] projection = new String[] { 
       ContactsContract.Contacts._ID, 
       ContactsContract.Contacts.DISPLAY_NAME, 
       ContactsContract.Contacts.HAS_PHONE_NUMBER 
     }; 
     String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "='1'"; 

     ContentResolver cr = getContentResolver(); 
     Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, selection, null, null); 
     if (cur.getCount() > 0) 
     { 
      while (cur.moveToNext()) { 
      String idc = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); 
      String namec = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
      myArr.add(namec); 
      } 
     } 

所以現在我有一個查詢只收集所需要的記錄。然而,即使在查詢數據集AND與第二個查詢時,它也很慢。真正的解決方案是刪除第二個查詢,但是收集少於整個數據庫的記錄是一個好主意。

回答

2

我會說,你查詢你的聯繫人數據的方式是錯誤的。

它看起來像從數據庫中獲取所有聯繫人的所有聯繫人數據,然後在while循環中篩選聯繫人。我建議從查詢中這樣做,是這樣的(未測試):

Cursor cur = cr.query(
    ContactsContract.Contacts.CONTENT_URI, 
    new String[] { "_ID", "DISPLAY_NAME" }, 
    "HAS_PHONE_NUMBER = ?", new String[] { "1" }, 
    null); 
+0

這是一個好主意。工作代碼被添加到問題中。 – erdomester

0

你紗廠將填充快了很多,如果你使用了break跳出你for -loop一旦您指定

num = i