应用程序需要阅读电话簿联系人并将其显示给用户,手机上有超过8000个联系人。 问题是在渲染屏幕上的所有联系人时,它会长时间停留。
请建议完成此任务的最佳方法。感谢
主要方法:
Cursor contactsCursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
LogUtils.d("@@@ cursorCount" + contactsCursor.getCount());
contacts = new ArrayList<ImportContactModel>();
importContactList = new ArrayList<ImportContactModel>();
showProgressDialog();
asyncLoader = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
fetchContacts();
return null;
}
protected void onPostExecute(Void result) {
// create an array of Strings, that will be put to our
// ListActivity
adapter = new ImportContactArrayAdapter(
ImportContactSelection.this, contacts);
contactList.setAdapter(adapter);
contactList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
initSearch();
dismissProgressDialog();
};
}.execute();
获取数据的类:
public void fetchContacts() {
String phoneNumber = null;
String email = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
String PROFILE_PIC = ContactsContract.CommonDataKinds.Phone.PHOTO_URI;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Uri EMAIL_CONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EMAIL_CONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String EMAIL = ContactsContract.CommonDataKinds.Email.DATA;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
null);
// Loop for every contact in the phone
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
ImportContactModel tempContact = new ImportContactModel();
String contact_id = cursor
.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor
.getColumnIndex(DISPLAY_NAME));
String image_uri = cursor.getString(cursor
.getColumnIndex(PROFILE_PIC));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor
.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
tempContact.setId(contact_id);
if (image_uri != null)
tempContact.setProfilePic(cursor.getString(cursor
.getColumnIndex(PROFILE_PIC)));
else
tempContact.setProfilePic("");
tempContact.setContactName(name);
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(
PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?",
new String[] { contact_id }, null);
// Get All Phone Numbers
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndex(NUMBER));
tempContact.setContactNo(phoneNumber);
break;
}
phoneCursor.close();
Cursor emailCursor = contentResolver.query(
EMAIL_CONTENT_URI, null, EMAIL_CONTACT_ID + "=?",
new String[] { contact_id }, null);
while (emailCursor.moveToNext()) {
String contactId = emailCursor.getString(emailCursor
.getColumnIndex(EMAIL_CONTACT_ID));
email = emailCursor.getString(emailCursor
.getColumnIndex(EMAIL));
tempContact.setEmail(email);
break;
}
emailCursor.close();
contacts.add(tempContact);
}
}
}
} 适配器类
public class ImportContactArrayAdapter extends ArrayAdapter<ImportContactModel> {
private final List<ImportContactModel> list;
private final Activity context;
private ImageLoader mImageLoader;
public ImportContactArrayAdapter(Activity context, List<ImportContactModel> list) {
super(context, R.layout.item_task_contact_select, list);
this.context = context;
this.list = list;
this.mImageLoader = ImageLoader.getInstance();
}
static class ViewHolder {
protected ImageView profilePic;
protected TextView contactName;
protected TextView contactNo;
protected CheckBox checkbox;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.item_task_contact_select, null);
final ViewHolder viewHolder = new ViewHolder();
//viewHolder.profilePic = (ImageView) view.findViewById(R.id.img_import_profilePic);
viewHolder.contactName = (TextView) view.findViewById(R.id.name_text);
viewHolder.contactNo = (TextView)view.findViewById(R.id.tag_text_1);
viewHolder.contactNo.setVisibility(View.VISIBLE);
viewHolder.contactNo.setTextSize(11);
viewHolder.checkbox = (CheckBox) view.findViewById(R.id.select_checkbox);
viewHolder.checkbox.setClickable(true);
viewHolder.checkbox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
ImportContactModel element = (ImportContactModel) viewHolder.checkbox
.getTag();
element.setSelected(buttonView.isChecked());
}
});
view.setTag(viewHolder);
viewHolder.checkbox.setTag(list.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
ImageView avatar = (ImageView) view.findViewById(R.id.img_avatar);
ImageView avatarBorder = (ImageView) view.findViewById(R.id.img_avatar_overlay);
ProgressBar avatarProgress = (ProgressBar) view.findViewById(R.id.img_avatar_progress);
if(!list.get(position).equals(""))
//holder.profilePic.setImageURI(Uri.parse(list.get(position).getProfilePic()));
mImageLoader.displayImage(list.get(position).getProfilePic(), avatar, new AvatarsImageLoadingListener(avatarProgress, avatarBorder, R.drawable.bg_nophoto));
holder.contactName.setText(list.get(position).getContactName());
holder.contactNo.setText(list.get(position).getContactNo());
holder.checkbox.setChecked(list.get(position).isSelected());
return view;
}
public ArrayList<ImportContactModel> getCheckList(){
ArrayList<ImportContactModel> tempList = new ArrayList<ImportContactModel>();
for(int i=0;i<list.size();i++){
if(list.get(i).isSelected()){
tempList.add(list.get(i));
LogUtils.d(""+list.get(i).getContactName());
}
}
return tempList;
}
}
所以它只显示加载屏幕了很长时间..
答案 0 :(得分:4)
您无需提取所有联系人以显示它们。 AsyncTask有publishProgress
方法。我没有Cursor
课程的经验,因为我更喜欢ORM,因此我会用伪代码编写,你必须自己调整它。
//in AsyncTask
protected Void doInBackground(params){
while(cursor.moveToNext()){
contactInfo = createContact(currentCursorValue);
publishProgress(contactInfo);
}
}
onProgressUpdate(contactInfo){
if(adapter==null){
//first time adapter setup
}
adapter.add(contactInfo);
adapter.notifyDataSetChanged();
}
这样,每次从Db中提取记录时,都会将其发布,并且会不断添加项目。用户不会注意到任何延迟,除非他尝试搜索尚未存在的项目,或者您想要实现快速滚动的大弹出信件。尽管如此,上面的代码并不是非常有效,因为每隔0.001秒左右发布一次进度并不是很聪明,所以你可以发布每20个结果,或者每秒发布一次,直到你。