黑马程序员技术交流社区

标题: ListView的优化及异步任务加载网络数据——3 [打印本页]

作者: zhoubinjian    时间: 2016-9-9 20:52
标题: ListView的优化及异步任务加载网络数据——3
五、ListView的其他优化:
1、尽量避免在BaseAdapter中使用static 来定义全局静态变量:
staticJava中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(比如Context的情况最多),这时就要尽量避免使用了。
2、尽量使用getApplicationContext
如果为了满足需求下必须使用Context的话:Context尽量使用Application Context,因为ApplicationContext的生命周期比较长,引用它不会出现内存泄露的问题
3、尽量避免在ListView适配器中使用线程:
因为线程产生内存泄露的主要原因在于线程生命周期的不可控制。之前使用的自定义ListView中适配数据时使用AsyncTask自行开启线程的,这个比用Thread更危险,因为Thread只有在run函数不 结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了线程执行池(ThreadPoolExcutor,这个类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。解决办法如下:
①、将线程的内部类,改为静态内部类。
②、在线程内部采用弱引用保存Context引用
示例代码:
public abstract class WeakAsyncTask extends  AsyncTask {
protected WeakReference mTarget;
public WeakAsyncTask(WeakTarget target) {
mTarget = new WeakReference(target);
}
@Override
protected final void onPreExecute() {
final WeakTarget target = mTarget.get();
if (target != null) {
this.onPreExecute(target);
}
}
        @Override
protected final Result doInBackground(Params... params) {
final WeakTarget target = mTarget.get();
if (target != null) {
return this.doInBackground(target, params);
} else {
return null;
}
}
@Override
protected final void onPostExecute(Result result) {
final WeakTarget target = mTarget.get();
if (target != null) {
this.onPostExecute(target, result);   
}
}
protected void onPreExecute(WeakTarget target) {
// No default action
}   
        protected abstract Result doInBackground(WeakTarget target, Params... params);   
protected void onPostExecute(WeakTarget target, Result result) {   
// No default action
}
}
六、ScrollViewListView的冲突问题:【摘自网络】
解决方法之一:
ScrollView添加一个ListView会导致listview控件显示不全,这是因为两个控件的滚动事件冲突导致。所以需要通过listview中的item数量去计算listview的显示高度,从而使其完整展示,如下提供一个方法供大家参考。
示例代码:
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
params.height += 5;//if without this statement,the listview will be a little short
listView.setLayoutParams(params);
}






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2