Android的加载接触过慢 [英] Android loading contacts is too slow

查看:120
本文介绍了Android的加载接触过慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序有5个纺纱填充在手机中的联系人。我使用下面的code来填充联系人数组,然后填充纺纱与阵列的项目(仅1飞旋在这里)。

in my app there are 5 spinners populated with the contacts in the phone. I am using the code below to populate an array with the contacts and then populate the spinners with the items of the array (just 1 spinner here).

当用户打开应用程序的微调填充,使用户可以选择一个名称为每个微调。 事情是,大约需要3秒,当用户打开应用程序加载与纺纱厂的布局。与codeI打后想通了,不管怎么可能微调器的应用程序,这个问题的根源是code表示填充与触点阵列。 我还发现了slowliness的原因:我跑我的兄弟的手机应用程序,并有它打开的速度,因为它应该。他只有30手机中的通讯录,而我有大约500名,他们大多是Facebook联系人。所以,我怎么能帮助这种情况?

When user opens the app the spinners are populated so the user can select one name for each spinner. Thing is, it takes around 3 secs to load the layout with the spinners when user opens the app. After playing with the code i figured out that no matter how may spinners are in the app, the source of the problem is the code that populates the array with the contacts. I also found the cause of the slowliness: i ran the app on my brothers phone and there it opened as fast as it should. He has only 30 contacts in the phone, while I have around 500, most of them are Facebook contacts. So how can I help this situation?

下面是独立纺纱的数量的问题,。如果太多的接触,这得到缓慢的:

Here is the problem, independently of the number of spinners. In case of too many contacts, this gets slow:

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

这是我如何填充每个微调(并使其显示前面选择的名称):

This is how I populate each spinner (and make them show the earlier selected name):

        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 based on the idea of Jesse van Assen:

原来,问题是第二个查询。我删除了这个创造了的预测的变量为列我需要:

Turned out that the problem was the second query. I deleted this one and created a "projection" variable for the columns i needed:

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

所以现在我有一个查询只收集需要的记录。然而,它是慢甚至与查询数据集,并与第二个查询。真正的解决办法是删除第二个查询,但是少收些记录较全的数据库是一个好主意。

So now I have one query that collects only the needed records. However it was slow even with the queried dataset AND with the second query. The real solution was to remove the second query, however collecting less record than the whole database is a great idea.

推荐答案

我要说的是,您查询您的联系人数据的方式是错误的。

I would say that the way you query your contacts data is wrong.

它看起来像你获取所有联系人与数据库中的所有联系人的数据,然后在过滤while循环的联系人。我建议从查询中这样做,是这样的(未测试):

It looks like you're fetching ALL your contacts with all the contact's data from the database, and then filtering the contacts in a while loop. I would suggest doing this from within the query, something like this (not tested):

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

这篇关于Android的加载接触过慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆