我正在开发一个需要从手机通讯录列表中读取多个联系人的应用。假设我有2000名成员加入我的电话簿,我成功获得所有联系人。但问题是,当我为2000联系人绘制布局时,我的设备会冻结,直到所有成员都不在屏幕上绘制。
使用contentResolver从电话簿获取所有联系人。
public void getAllContacts(ContentResolver cr)
{
try {
final String[] PROJECTION = new String[]
{ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
final String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
name1.clear();
phno1.clear();
MatrixCursor mc = new MatrixCursor(new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
});
String lastNumber = "";
Cursor c1 = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC");
while(c1.moveToNext())
{
try {
String name = c1.getString(c1.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = c1.getString(c1.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
String test = number.replaceAll(" ", "");
if (!lastNumber.contains(test)) {
lastNumber = test;
mc.addRow(new String[]{name, test});
}
}catch (Exception e)
{
e.printStackTrace();
}
}
c1.close();
while (mc.moveToNext())
{
String value = "";
String name =mc.getString(mc.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = mc.getString(mc.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String result = name.replaceAll("[!.#^$%&()+@_|?*<\":>+\\[\\]/']", " ");
String test = phoneNumber.replaceAll("[!.#^$%&()+@_|?*<\":>+\\[\\]/']", "");
String numbers = test.substring(Math.max(0, test.length() - 10));
name1.add(result);
phno1.add(numbers);
}
mc.close();
}catch (Exception e)
{
e.printStackTrace();
}
}
Drawing contact layout from added contact to Arraylist.
public void Drawcontactlayout()
{
try {
contactlist.removeAllViews(); // Linear Layout
for (int i = 0; i < name1.size(); i++)
{
try {
int endIndex = searchtext.length();
String nm = name1.get(i).toString();
String test1 = phno1.get(i).toString();
String s = searchtext.substring(0, endIndex);
String p = test1.substring(0, endIndex);
String n = nm.substring(0, endIndex);
String searchv = s.toUpperCase();
if (n.equalsIgnoreCase(s) || p.equalsIgnoreCase(s) || nm.contains(s) || nm.contains(searchv) || test1.contains(s) || searchtext.equalsIgnoreCase("")) {
rl1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout layout = new RelativeLayout(ct);
layout.setLayoutParams(rl1);
final int finalI = i;
rl1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
TextView iname = new TextView(ct);
iname.setPadding(width / 70, 0, 0, 0);
iname.setId(i + 1);
iname.setText(name1.get(i).toString());
iname.setGravity(Gravity.CENTER);
iname.setTextSize(12);
iname.setTextColor(getResources().getColor(R.color.white_light));
iname.setLayoutParams(rl1);
rl1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
rl1.addRule(RelativeLayout.BELOW, iname.getId());
rl1.setMargins(width / 70, width / 70, 0, 0);
TextView mobile = new TextView(ct);
mobile.setId(i + 2);
mobile.setTextSize(12);
mobile.setText(phno1.get(i).toString());
mobile.setTextColor(getResources().getColor(R.color.white_light));
mobile.setLayoutParams(rl1);
rl1 = new RelativeLayout.LayoutParams(width / 12, width / 12);
rl1.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
rl1.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
rl1.setMargins(0, 0, width / 50, 0);
final TextView check = new TextView(ct);
check.setId(i + 3);
try {
if (checked) {
check.setBackgroundResource(android.R.drawable.checkbox_on_background);
names.add(name1.get(finalI).toString());
numbers.add(phno1.get(finalI).toString());
} else {
if (testing[finalI] != false) {
check.setBackgroundResource(android.R.drawable.checkbox_on_background);
} else {
names.clear();
numbers.clear();
check.setBackgroundResource(android.R.drawable.checkbox_off_background);
}
}
check.setLayoutParams(rl1);
checkbox.add(check);
}catch (Exception e)
{
e.printStackTrace();
}
check.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (CommanString.REMAINING == 0) {
Toast.makeText(ct, "Insuficient Slot Invitees, please purchase more!", Toast.LENGTH_SHORT).show();
} else {
if (testing[finalI] == false) {
testing[finalI] = true;
names.add(name1.get(finalI).toString());
numbers.add(phno1.get(finalI).toString());
check.setBackgroundResource(android.R.drawable.checkbox_on_background);
} else if (testing[finalI] == true) {
testing[finalI] = false;
Drawable img4 = ct.getResources().getDrawable(android.R.drawable.checkbox_off_background);
img4.setBounds(0, 0, width / 12, width / 12);
chkall.setCompoundDrawables(null, null, img4, null);
chkall.setCompoundDrawablePadding(width / 50);
isChecked = false;
checked = false;
for (int i = 0; i < names.size(); i++) {
if (names.get(i).toString().equalsIgnoreCase(name1.get(finalI).toString()) || numbers.get(finalI).toString().equalsIgnoreCase(phno1.get(finalI).toString())) {
// CommanString.REMAINING = CommanString.REMAINING +1;
names.remove(i);
numbers.remove(i);
}
}
check.setBackgroundResource(android.R.drawable.checkbox_off_background);
}
}
}catch (Exception e)
{
e.printStackTrace();
}
}
});
rl1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, width / 300);
rl1.setMargins(0, width / 50, 0, 0);
TextView margin = new TextView(ct);
margin.setBackgroundColor(Color.parseColor("#cccccc"));
margin.setLayoutParams(rl1);
layout.addView(iname);
layout.addView(mobile);
layout.addView(check);
contactlist.addView(layout);
contactlist.addView(margin);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
答案 0 :(得分:0)
为了使问题更容易理解,您应该发布一些代码片段。但是从您的问题来看,似乎您必须使用listview或RecyclerView(更喜欢它更有效)来列出所有联系人。当你在列表中显示很多项目时,android不会为每个项目分别绘制布局(因此它不会为所有200个联系人绘制布局),以获取有关android如何为RecylerView中的每个项目生成布局的更多信息,你可以参考this。
冻结应用程序的可能原因可能是在UI线程上加载数据。如果您正在执行从数据库加载大量数据或进行http调用以从网络或任何其他密集型任务获取数据的任务,则应使用AsyncTask。此类允许您执行后台操作并在UI线程上发布结果,而无需操作线程或处理程序。要了解AsyncTask,您可以参考this