2011-09-04 61 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