ListView显示数据的问题 同求解决方案,我用ListView显示音乐列表,有200首音乐,读取显示的就很慢,大约要五六秒钟才能显示出来;而天天动听只要2秒左右就可以全显示出来。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 listview延迟加载?貌似apidemo里面有例子 建议看一下 API Demos/View/Lists/13.Slow Adapter 这个例子。Demo 用的是延迟加载。 子线程中去处理list要显示的数据,然后处理完通过handler通知UI更新listLZ,把你的联系人查询语句贴出来,可以自己通过添加SQL语句的过滤,只获取有用的联系人信息,而不是把联系人的所有信息都取出来。 private List<Map<String, Object>> getData() { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); String[] p = new String[] {Contacts._ID,Contacts.DISPLAY_NAME,"smart",Contacts.LOOKUP_KEY,Contacts.HAS_PHONE_NUMBER}; Cursor cur = getContentResolver().query(Contacts.CONTENT_URI, p, null, null, null); if (cur.moveToFirst()) { int idColumn = cur.getColumnIndex(Contacts._ID); int displayNameColumn = cur.getColumnIndex(Contacts.DISPLAY_NAME); int smartColumn = cur.getColumnIndex("smart"); int lookupColumn = cur.getColumnIndex(Contacts.LOOKUP_KEY); do { Map<String, Object> map = new HashMap<String, Object>(); String contactId = cur.getString(idColumn); String displayName = null; displayName = cur.getString(displayNameColumn); String smart = cur.getString(smartColumn); String lookup = cur.getString(lookupColumn); int resource; if (lookup.startsWith(IS_GSM_CARD)) { resource = R.drawable.ic_contact_picture_g; } else if (lookup.startsWith(IS_CDMA_CARD)) { resource = R.drawable.ic_contact_picture_c; } else { resource = R.drawable.ic_contact_picture_local; } map.put("contactId", contactId); map.put("smart", smart); map.put("contactName", displayName); map.put("lookup", resource); int phoneCount = cur .getInt(cur .getColumnIndex(Contacts.HAS_PHONE_NUMBER)); String newNumber = ""; if (phoneCount > 0) { Cursor phones = getContentResolver() .query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId + " and " + ContactsContract.CommonDataKinds.Phone.TYPE + "=" + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE, null, null); if (phones != null && phones.moveToNext()) { String phoneNumber = phones .getString(phones .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); String[] splitNumber = phoneNumber.split("-"); for (int i = 0; i < splitNumber.length; i++) { newNumber += splitNumber[i]; } } } else { newNumber += NONE_TELEPHONENUMBER; } map.put("contactNumber", newNumber); list.add(map); } while (cur.moveToNext()); } return list; } 有用了你的方案了,不过还是要等,除非做个ProgressDialog提示不过我想实现的是进入应用程序就可以马上显示出来 以前做过类似的功能,代码已经找不到了,但印象里面和你的差不多。你可以在你的代码中加一些log打印一下时间,看看在那些处理上面耗时多再想办法优化吧。int idColumn = cur.getColumnIndex(Contacts._ID);int displayNameColumn = cur.getColumnIndex(Contacts.DISPLAY_NAME);int smartColumn = cur.getColumnIndex("smart");int lookupColumn = cur.getColumnIndex(Contacts.LOOKUP_KEY);类似的定义是否可以放到函数开始,没必要定义到循环内部吧,这个具体是否有影响我也不清楚,或许吧。if (phones != null && phones.moveToNext())这判断是不是可以改成嵌套形式的,没必要每次都判断phones != null根据你的代码可以推测你大概的目的,感觉逻辑上没有太大的优化余地了。实在达不到要求,就改成非同期更新吧。 首先很感谢你的回答不过那些变量我没定义在循环的内部!只是在一个if里面还有你的建议用Log打印时间我试过了!确实在是在这段数据库操作上耗时最多的! 突然发现原来自带的会那么快是因为他未读取号码!只显示了姓名!也看了他的API Demo里面有读取联系人和号码的代码,用的还是过时的People 已经解决主要问题是每次循环的时候都用去查询一次数据库!这样大大降低了效率我的解决方案是: 在onCreat中先把所有号码查出放在一个List里面然后再查询联系人!根据联系人的Id和刚才的List做匹配这样就减少了N次的数据库查询! 最后感谢楼上所有回答我的兄弟特别感谢 chenkejun 关于Android View与Drawable的问题 求解!!Android的HttpURLConnection连接应用 手机root指令问题 关于Listview菜鸟问题 问几个菜鸟问题 addView一个LinearLayout的布局显示有问题 如何实现这样的一个动态布局? android静默卸载怎么实现? SlidingMenu滑动事件和点击事件冲突问题 Android dpi单位 Gallery遇到的问题【急需解决】 Income Tax ID和VAT ID怎么填啊?
Demo 用的是延迟加载。
LZ,把你的联系人查询语句贴出来,可以自己通过添加SQL语句的过滤,只获取有用的联系人信息,而不是把联系人的所有信息都取出来。
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); String[] p = new String[] {Contacts._ID,Contacts.DISPLAY_NAME,"smart",Contacts.LOOKUP_KEY,Contacts.HAS_PHONE_NUMBER};
Cursor cur = getContentResolver().query(Contacts.CONTENT_URI, p,
null, null, null); if (cur.moveToFirst()) { int idColumn = cur.getColumnIndex(Contacts._ID);
int displayNameColumn = cur.getColumnIndex(Contacts.DISPLAY_NAME);
int smartColumn = cur.getColumnIndex("smart");
int lookupColumn = cur.getColumnIndex(Contacts.LOOKUP_KEY); do {
Map<String, Object> map = new HashMap<String, Object>();
String contactId = cur.getString(idColumn); String displayName = null; displayName = cur.getString(displayNameColumn);
String smart = cur.getString(smartColumn);
String lookup = cur.getString(lookupColumn); int resource;
if (lookup.startsWith(IS_GSM_CARD)) {
resource = R.drawable.ic_contact_picture_g;
} else if (lookup.startsWith(IS_CDMA_CARD)) {
resource = R.drawable.ic_contact_picture_c;
} else {
resource = R.drawable.ic_contact_picture_local;
}
map.put("contactId", contactId);
map.put("smart", smart);
map.put("contactName", displayName);
map.put("lookup", resource);
int phoneCount = cur
.getInt(cur
.getColumnIndex(Contacts.HAS_PHONE_NUMBER));
String newNumber = "";
if (phoneCount > 0) {
Cursor phones = getContentResolver()
.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = "
+ contactId
+ " and "
+ ContactsContract.CommonDataKinds.Phone.TYPE
+ "="
+ ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,
null, null);
if (phones != null && phones.moveToNext()) {
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); String[] splitNumber = phoneNumber.split("-");
for (int i = 0; i < splitNumber.length; i++) {
newNumber += splitNumber[i];
} }
} else {
newNumber += NONE_TELEPHONENUMBER;
}
map.put("contactNumber", newNumber);
list.add(map);
} while (cur.moveToNext());
}
return list;
}
有用了你的方案了,不过还是要等,除非做个ProgressDialog提示
不过我想实现的是进入应用程序就可以马上显示出来
int displayNameColumn = cur.getColumnIndex(Contacts.DISPLAY_NAME);
int smartColumn = cur.getColumnIndex("smart");
int lookupColumn = cur.getColumnIndex(Contacts.LOOKUP_KEY);
类似的定义是否可以放到函数开始,没必要定义到循环内部吧,这个具体是否有影响我也不清楚,或许吧。if (phones != null && phones.moveToNext())
这判断是不是可以改成嵌套形式的,没必要每次都判断phones != null根据你的代码可以推测你大概的目的,感觉逻辑上没有太大的优化余地了。
实在达不到要求,就改成非同期更新吧。
突然发现原来自带的会那么快是因为他未读取号码!只显示了姓名!
也看了他的API Demo里面有读取联系人和号码的代码,用的还是过时的People
主要问题是每次循环的时候都用去查询一次数据库!这样大大降低了效率我的解决方案是:
在onCreat中先把所有号码查出放在一个List里面
然后再查询联系人!根据联系人的Id和刚才的List做匹配
这样就减少了N次的数据库查询!
特别感谢 chenkejun