我们在使用ListView时 用户时长会 连续滚动数屏,且滚动过程中会触发所有的getView的异步任务,getView线程加载图片则会 开很多条线程或者是线程池不够用 堵塞在 前面的getView任务中。直到 逐个执行完成 到达 当前显示的屏幕。
导致问题:getView需要执行很多个异步任务造成堵塞(下载不看的图片造成用户流量损失),且无法再第一时间展示用户想看的界面。
个人做了小demo 可以再ListView滚动结束后 只加载当前用户可视区的图片。减少堵塞情况。
package com.sk.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
public class TestActivity extends Activity {
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
lv = (ListView) findViewById(R.id.test_lv);
List<String> list = new ArrayList<String>();
for (int i = 0; i < 500; i++) {
list.add("当前第:" + i + "个 item");
}
final ListViewAdapter adapter = new ListViewAdapter(this, list, lv);
lv.setAdapter(adapter);
lv.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
// TODO Auto-generated method stub
switch (arg1) {
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:// 滑动状态
adapter.threadFlag = false;
break;
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:// 停止
adapter.threadFlag = true;
adapter.startThread();
break;
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 触摸listView
adapter.threadFlag = false;
break;
default:
}
}
@Override
public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
}
});
}
}
package com.sk.test;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class ListViewAdapter extends BaseAdapter {
List<String> list;
ListView lv;
Context mContext;
Boolean threadFlag = true;
public ListViewAdapter(Context context, List<String> list, ListView lv) {
this.list = list;
this.lv = lv;
mContext = context;
}
/**
* 开始下载当前屏幕的图片 把要做的任务加入 tag 然後由耗时操作 避免每次getView 都创建线程 堵塞 应用
*/
public void startThread() {
Log.i("ListViewAdapter", "execute startThread!!");
int start = lv.getFirstVisiblePosition();
int end = lv.getLastVisiblePosition();
int num = end - start;
for (int i = 0; i <= num; i++) {
View view = lv.getChildAt(i);
Log.i("ListViewAdapter", "position=" + i + " view=" + view);
if (view != null) {
TextView tv = (TextView) view.getTag(R.string.tag_view_key);
String value = (String) view.getTag(R.string.tag_value_key);
tv.setText(value);
}
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return list.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
TextView tv = null;
if (arg1 == null) {
arg1 = new LinearLayout(mContext);
tv = new TextView(mContext);
/**
* R.string.tag_view_key view setTag必须用 android 自动生成id 可以再values
* string 随便声明个值 使用该id作为 唯一id使用
*/
arg1.setTag(R.string.tag_view_key, tv);
((LinearLayout) arg1).addView(tv);
} else {
tv = (TextView) arg1.getTag(R.string.tag_view_key);
}
String str = "position:" + arg0 + "-滑动停止设置该文本-" + list.get(arg0);
if (threadFlag) {
tv.setText(str);
} else {
// 先展示默认 等滚动停止 会触发加载
tv.setText("position:" + arg0);
}
arg1.setTag(R.string.tag_value_key, str);
return arg1;
}
}
demo 下载地址: http://download.csdn.net/detail/sunkeperfect/7482469