我正在使用AsyncTasks将数据加载到listview中的项目以避免延迟滚动,我从包括位图的webservices获取所有内容,但我已覆盖该部分。
从我收集的内容来看,运行线程的项目将不会被回收,只有当线程停止时,线程至少保持运行,我放置了一些system.out.println来跟踪发生的事情,我注意到了如果我快速向下滚动列表视图,说20个事件,即使我只看到3个或4个,我看到所有System.out.println
的logcat上的输出,每1/4秒左右一个左右,这大致是时间它需要加载每个图像和其他文本。
所以我需要等待一段不可接受的时间直到它到达当前可见的项目,因为在任何给定时刻只能运行一个AsyncTask,我知道有多种方法可以运行多个线程,但我想避免这条路径因为我担心它可能会使电话过载,在这种情况下,我很确定它会导致out.of.memory错误。
如果我滚动得太快,我会滚动尚未加载的项目,仍然是他们的线程跳转到队列,我在自定义适配器中运行AsyncTask,每次创建项目时线程启动或其线程排队当快速滚动时,一些不再可见的项目仍然会将它们的线程排队,并且它们最终会延迟那些在线程完成后立即被销毁的可见内容。
我已经尝试在自定义适配器中使用setRecyclerListener,但只加载了初始可见项,当向下滚动时,不会显示任何内容。
如果您有任何建议,请不要费心浏览代码,但无论如何我都会留在这里,但我真正想要的是避免这种情况的想法,他们可能需要对我的代码进行微调或重建全班只要他们工作。
关于我发布的代码是使用recyclerListener,我可能缺少的一件事是使用监听器我必须将它与listview关联,我在自定义适配器类中,所以在listview主类我将listview声明为一个公共变量,然后将其放入自定义适配器类中。
/////////////////////////////////
class CustomAdapterEvents extends ArrayAdapter<String>{
private AsyncTask<String, Void, JSONObject> listviewTextAssembler;
private AsyncTask<String, Void, Bitmap> listviewImageAssembler;
public CustomAdapterEvents(Context context, ArrayList<String> IDlist) {
super(context, R.layout.custom_row_events, IDlist);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getContext());
LayoutInflater inflater2 = LayoutInflater.from(getContext());
final View customView = inflater.inflate(R.layout.custom_row_events, parent, false);
final View customView2 = inflater2.inflate(R.layout.custom_row_trending, parent, false);
//Trending Items
final TextView trendingTitle = (TextView) customView2.findViewById(R.id.trendingEventTitle);
final TextView trendingDate = (TextView) customView2.findViewById(R.id.trendingEventDate);
final TextView trendingHour = (TextView) customView2.findViewById(R.id.trendingEventHour);
final TextView trendingSpot = (TextView) customView2.findViewById(R.id.trendingEventSpot);
ImageView trendingImage = (ImageView) customView2.findViewById(R.id.trendingEventImage);
//Trending Items
final TextView listviewTitle = (TextView) customView.findViewById(R.id.listEventTitle);
final TextView listviewDate = (TextView) customView.findViewById(R.id.listEventDate);
final TextView listviewHour = (TextView) customView.findViewById(R.id.listEventHour);
final TextView listviewSpot = (TextView) customView.findViewById(R.id.listEventSpot);
final ImageView listviewImage = (ImageView) customView.findViewById(R.id.listEventImage);
///////////////
final RotateAnimation anim = new RotateAnimation(0f, 359f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
final ImageView loading = (ImageView) customView.findViewById(R.id.loadingView);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);
loading.startAnimation(anim);
TypeFaceUtil.overrideFont(getContext(), "SERIF", "fonts/lato-reg.ttf");
MainScreen.listview.setRecyclerListener(new AbsListView.RecyclerListener() {
@Override
public void onMovedToScrapHeap(View view) {
System.out.println("cancel that *%$# for *%#!'s sake!");
listviewImageAssembler.cancel(true);
listviewTextAssembler.cancel(true);
}
});
///LISTVIEW PROCESS
listviewTextAssembler = new AsyncTask<String, Void, JSONObject>(){
protected JSONObject doInBackground(String... params) {
int position = Integer.parseInt(params[0]);
//GET JSON
String result = "";
WebConnector connector = new WebConnector();
try {result = connector.getResponseText("listview/1");}
catch (MalformedURLException e) {}
catch (IOException e){}
/////////
JSONArray jsonArray = new JSONArray();
JSONObject completeJson = new JSONObject();
String thumbnail = "";
JSONObject eventJson = new JSONObject();
try {
completeJson = new JSONObject(result);
jsonArray = completeJson.getJSONArray("eventos");
eventJson = jsonArray.getJSONObject(position-1);
thumbnail = eventJson.getString("thumbnail");
}catch (JSONException e){e.printStackTrace();}
System.out.println("EVENT > "+eventJson);
return eventJson;
}
@Override
protected void onProgressUpdate(Void... values) {
}
@Override
public void onPostExecute(JSONObject eventJson)
{
loading.setAnimation(null);
loading.setVisibility(View.GONE);
String id = "";
String title = "";
String date = "";
String hour = "";
String address = "";
Bitmap image = null;
try{
title = eventJson.getString("title");
date = eventJson.getString("date");
hour = eventJson.getString("time");
address = eventJson.getString("city");
}catch (JSONException e){e.printStackTrace();}
listviewTitle.setText(title);
listviewDate.setText(date);
listviewHour.setText(hour);
listviewSpot.setText(address);
}
};
listviewImageAssembler = new AsyncTask<String, Void, Bitmap>(){
protected Bitmap doInBackground(String... params) {
int position = Integer.parseInt(params[0]);
//GET JSON
String result = "";
WebConnector connector = new WebConnector();
try {result = connector.getResponseText("listview/1");}
catch (MalformedURLException e) {}
catch (IOException e){}
/////////
JSONArray jsonArray = new JSONArray();
JSONObject completeJson = new JSONObject();
String thumbnail = "";
JSONObject eventJson = new JSONObject();
try {
completeJson = new JSONObject(result);
jsonArray = completeJson.getJSONArray("eventos");
eventJson = jsonArray.getJSONObject(position);
thumbnail = eventJson.getString("thumbnail");
}catch (JSONException e){e.printStackTrace();}
System.out.println("EVENT > "+eventJson);
Bitmap image = connector.drawable_from_url(thumbnail);
return image;
}
@Override
public void onPostExecute(Bitmap image)
{
listviewImage.setImageBitmap(image);
image = null;
}
};
String pos = ""+position;
listviewTextAssembler.execute(pos);
listviewImageAssembler.execute(pos);
return customView;
}
}
答案 0 :(得分:0)
我最终使用: listviewTextAssembler.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,pos); 代替: listviewTextAssembler.execute(POS);
pos只是我传递的字符串......
这是我试图避免的,但它现在必须要做...将期待有关如何杀死不再有用的运行线程或从队列中删除其他人或使用Last的建议在First out模型中,将线程数限制为5,这是一次可见的最大项目。不缺乏想法,只缺少技术诀窍但我认为这都是学习曲线的一部分。
干杯