в моем приложении есть 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);
}
Решение основано на идее Джесси ван Ассена:
Оказалось, что проблема была во втором запросе.Я удалил этот и создал переменную " projection " для нужных мне столбцов:
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);
}
}
Так что теперь у меня есть один запрос, который собирает только необходимые записи.Однако это было медленно даже с запрашиваемым набором данных И со вторым запросом.Реальным решением было удалить второй запрос, однако собирать меньше записей, чем вся база данных, - отличная идея.