【问题标题】:How do I increase the fetching speed of an arraylist?如何提高数组列表的获取速度?
【发布时间】:2019-07-06 21:14:26
【问题描述】:

我正在使用Arraylist 来获取我的应用程序中的所有可用联系人。这效率不高,因为Arraylist 需要很长时间才能获取和填充Listview,因为几乎有600+ contacts

我正在寻找一种性能更好的替代方法。

虽然我搜索了其他相关问题,但我找不到方便的问题。

这是我的java代码:

private List<String> getContactList() {
      List<String> stringList=new ArrayList<>();
      ContentResolver cr = context.getContentResolver();
      Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
        null, null, null, null);

      if ((cur != null ? cur.getCount() : 0) > 0) {
        while (cur != null && cur.moveToNext()) {
          String id = cur.getString(
            cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(
            ContactsContract.Contacts.DISPLAY_NAME)
          );

          if (cur.getInt(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[]{id}, null
               );

               while (pCur.moveToNext()) {
                 String phoneNo = pCur.getString(pCur.getColumnIndex(
                 ContactsContract.CommonDataKinds.Phone.NUMBER));                  
                 Log.v("Data : ",""+id+" "+name+" "+phoneNo);
                 stringList.add(id);
                 stringList.add(name);
                 stringList.add(phoneNo);
               }
               pCur.close();
             }
            }
          }
          if(cur!=null){
            cur.close();
          }
          return stringList;
        }   

【问题讨论】:

  • ArrayList 在这里不是问题,它只是一个CollectionContentResolver 查询需要时间,因此您最好在工作线程上执行此操作。而ContentResolver 确实支持分页,因此您还可以逐页加载数据..
  • 检查这个 - stackoverflow.com/a/51064521/7649582 。也许它会帮助你。
  • 请检查stackoverflow.com/questions/10844672/…,如果这能解决您的查询,您的实际问题是从数组列表中获取contacts 获取对象不是问题。

标签: java android listview arraylist android-contacts


【解决方案1】:

您的查询效率低下,您目前正在为每个联系人执行一个非常慢的查询,您可以通过一个大查询(非常快)获得所有信息:

String[] projection = new String[] { Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER };
Cursor c = cr.query(Phone.CONTENT_URI, projection, null, null, null);
while (c.moveToNext()) {
   long contactId = c.getLong(0);
   String name = c.getString(1);
   String phone = c.getString(2);
   Log.i("Phones", "got contact phone: " + contactId + " - " + name + " - " + phone);
}
c.close();

【讨论】:

  • 抱歉来晚了,我试试这个方法。
【解决方案2】:

您可以考虑使用Paging 库:https://developer.android.com/topic/libraries/architecture/paging/

它的设计理念是列表仅显示一定数量的项目,因此实际上无需加载超出其可能显示的方式。例如,一个 ListView 可能只显示 10 个联系人,因此无需获取 600 个联系人。

相反,当用户滚动时,分页库将获取更少量的数据,从而消除 600 个联系人的加载时间、600 个联系人的内存等等......从而提高效率。

【讨论】:

    【解决方案3】:

    如果您担心速度,我会尝试使用 Set,尽管 ArrayList 中有 600 多个联系人应该不成问题。当数据集达到数百万甚至更多时,它就会成为一个问题。我会尝试查看您的代码中的任何其他低效之处。

    就 Set 而言,两种最常见的 Java 数据结构是 HashSet 和 TreeSet。 TreeSet 如果你想对集合进行排序。 HashSet 稍微快一点,但是你失去了排序。两者的访问时间都是 O(1)。

    【讨论】:

    • HashSet 对于我的目的来说似乎很明显。因为联系人应该按字母顺序格式化。
    猜你喜欢
    • 1970-01-01
    • 2018-09-22
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 2019-06-22
    • 2019-04-11
    • 2018-10-10
    相关资源
    最近更新 更多