Android 加载联系人太慢

2023-12-01

在我的应用程序中,有 5 个旋转器填充了手机中的联系人。我使用下面的代码用联系人填充数组,然后用数组的项目填充微调器(这里只有 1 个微调器)。

当用户打开应用程序时,会填充微调器,以便用户可以为每个微调器选择一个名称。 事实是,当用户打开应用程序时,使用微调器加载布局大约需要 3 秒。在玩完代码后,我发现无论应用程序中的旋转器有多少,问题的根源都是用联系人填充数组的代码。 我还找到了速度缓慢的原因:我在我兄弟的手机上运行了该应用程序,它的打开速度与应有的速度一样快。他手机里只有30个联系人,而我有大约500个,其中大部分是Facebook联系人。那么我该如何帮助这种情况呢?

这就是问题所在,与旋转器的数量无关。如果联系人太多,速度会变慢:

 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);
        }

Solution基于 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);
            }
        }

所以现在我有一个查询仅收集所需的记录。然而,即使使用查询的数据集和第二个查询,它也很慢。真正的解决方案是删除第二个查询,但是收集比整个数据库更少的记录是一个好主意。


我想说你查询联系人数据的方式是错误的。

看起来您正在从数据库中获取所有联系人及其所有联系人数据,然后在 while 循环中过滤联系人。我建议从查询中执行此操作,如下所示(未测试):

Cursor cur = cr.query(
    ContactsContract.Contacts.CONTENT_URI, 
    new String[] { "_ID", "DISPLAY_NAME" },
    "HAS_PHONE_NUMBER = ?", new String[] { "1" }, 
    null);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 加载联系人太慢 的相关文章

随机推荐