在滚动侦听器上调用 asynctask 三次或多次在 listview 上滚动一次
Posted
技术标签:
【中文标题】在滚动侦听器上调用 asynctask 三次或多次在 listview 上滚动一次【英文标题】:On scroll listener calling asynctask twice thrice or some times more on scrolling once on listview 【发布时间】:2015-10-23 20:40:14 【问题描述】:当我通过 api 从 web 加载数据时,用户在 listview 中滚动到底部,但是当我在 listview 上滚动一次时,它会在我的活动中多次调用 asynctask,这会导致 listview 中出现重复数据,并且在出现异常的情况下会出现很多活动中的对话框和吐司,当我滚动到底部时,只需在滚动方法上触摸我的列表视图,就会触发多次调用 asynctask,所以请告诉我如何防止这种情况。
这是我的 onscroll 方法代码。
listView.setOnScrollListener(new OnScrollListener()
// boolean mIsScrollingUp;
// int mLastFirstVisibleItem;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
// TODO Auto-generated method stub
if(scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL)
userscrolled=true;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
// TODO Auto-generated method stub
int lasinscren = firstVisibleItem + visibleItemCount;
if(userscrolled&&(lasinscren==totalItemCount)&&!lodinmore&&(visibleItemCount<totalItemCount)&&havedata)
progress = true;
if(Search_API==false)
if(connectionDetector.isConnectintoInternet())
System.out.println("inside listview on scroll function");
darList_task = new DAR_list_task(DAR_Activity.this).execute();
lodinmore = true;
else
Toast.makeText(getApplicationContext(), "No internet connection", Toast.LENGTH_SHORT).show();
else
new search_task(DAR_Activity.this).execute();
);
这是我的异步任务
public class DAR_list_task extends AsyncTask<Void, Void, Void>
Context activity;
public DAR_list_task(Context activity)
// TODO Auto-generated constructor stub
this.activity = activity;
@Override
protected void onPreExecute()
// TODO Auto-generated method stub
super.onPreExecute();
if(progress==true)
if(limit==0)
dialog = new Dialog(DAR_Activity.this);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
LinearLayout linearLayout = (LinearLayout)getLayoutInflater().inflate(R.layout.dialog_progress, null);
dialog.setContentView(linearLayout);
ProgressBar progressBar1 = (ProgressBar)findViewById(R.id.progress_dialog);
dialog.setCancelable(false);
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
dialog.getWindow().setGravity(Gravity.CENTER);
else
progressBar.setVisibility(View.VISIBLE);
@Override
protected Void doInBackground(Void... params)
// TODO Auto-generated method stub
response=null;
lodinmore = true;
URL Url;
try
byte[] data;
data = login_id.getBytes("UTF-8");
String login_base_64 = Base64.encode(data);
data = gcm_id.getBytes("UTF-8");
String gcm_base64= Base64.encode(data);
if(url.contentEquals(""))
Url = new URL(getResources().getString(R.string.dar_list_view));
else
Url = new URL("http://"+url+"/smart_oms/dar_app/view_dar.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("login_id", login_base_64));
nameValuePairs.add(new BasicNameValuePair("gcm_id", gcm_base64));
nameValuePairs.add(new BasicNameValuePair("limit", String.valueOf(limit)));
HttpURLConnection httpURLConnection = (HttpURLConnection)Url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setUseCaches(false);
httpURLConnection.setDoOutput(true);
OutputStream os = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
bufferedWriter.write(getQueryString(nameValuePairs));
bufferedWriter.flush();
bufferedWriter.close();
os.close();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
response = BufferReaderMaker.readContentFromIS(inputStream);
catch( final UnknownHostException ex)
runOnUiThread(new Runnable()
public void run()
Toast.makeText(getApplicationContext(), ex.getMessage(), Toast.LENGTH_SHORT).show();
);
catch (final ConnectTimeoutException e)
// TODO: handle exception
runOnUiThread(new Runnable()
public void run()
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
);
catch (Exception e)
// TODO: handle exception
return null;
@Override
protected void onPostExecute(Void result)
// TODO Auto-generated method stub
super.onPostExecute(result);
Object json = null;
try
if(response!=null)
if(progress==false)
dar_List_Items.clear();
dar_Aadapter = new DAR_Aadapter(DAR_Activity.this, dar_List_Items);
listView.setAdapter(dar_Aadapter);
dar_Aadapter.notifyDataSetChanged();
try
json = new JSONTokener(response).nextValue();
catch (JSONException e1)
// TODO Auto-generated catch block
ErrorDialog errorDialog = new ErrorDialog();
errorDialog.Dialog(activity, statusCode, response, login_id, "", new DAR_list_task(activity));
if(json instanceof JSONArray)
havedata=false;
Toast.makeText(getApplicationContext(), "No More DAR", 0).show();
else if(json instanceof JSONObject)
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("view_dar_detail");
for(int i =0 ;i<jsonArray.length();)
JSONObject json_data = jsonArray.getJSONObject(i);
String dar_id = json_data.optString("customer_id");
String Customer_name = json_data.optString("customer_name");
String Contacted= json_data.optString("contact_person_name");
String product = json_data.optString("product");
String status = json_data.optString("dar_status");
String Contact_type = json_data.optString("contact_type");
String created_date = json_data.optString("dar_created_date");
String request_date = json_data.optString("requeste_date");
DAR_List_Item dar_List_Item = new DAR_List_Item(dar_id,Customer_name, Contacted, Contact_type, product, status, created_date, request_date,"abcd");
dar_List_Items.add(dar_List_Item);
i++;
int index = listView.getFirstVisiblePosition();
View v= listView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
listView.setAdapter(null);
DAR_Aadapter aadapter = new DAR_Aadapter(DAR_Activity.this, dar_List_Items);
listView.setAdapter(aadapter);
aadapter.notifyDataSetChanged();
listView.setSelectionFromTop(index, top);
else
ErrorDialog errorDialog = new ErrorDialog();
errorDialog.Dialog(activity, statusCode, response, login_id, "", new DAR_list_task(activity));
lodinmore = false;
lodinmore = false;
catch (JSONException e)
// TODO Auto-generated catch block
ErrorDialog errorDialog = new ErrorDialog();
errorDialog.Dialog(activity, statusCode, response, login_id, "", new DAR_list_task(activity));
if(progress==true)
if(limit==0)
dialog.dismiss();
else
progressBar.setVisibility(View.GONE);
if(json instanceof JSONObject)
limit = limit +10;
请帮帮我,我已经尝试了很多东西,比如使用标志值等等,但没有一个对我有用。
如何防止调用asynctask多次调用? 当我滚动到底部并触摸列表时如何防止触发异步任务?
【问题讨论】:
***.com/a/24713773/975292 @SeshuVinay 我应该如何实现为什么android中有方法而不是它不能正常工作? 【参考方案1】:有一个解决方法:
final int lastItem = firstVisibleItem + visibleItemCount;
if(lastItem == totalItemCount)
if(lastLastitem !=lastItem) //to avoid multiple calls for last item, declare it as a field in your Activity
lastLastitem = lastItem;
// Your async task here
【讨论】:
什么是 lat item 和 lastlastitem 请检查我上面的 onscroll 代码并告诉我修改 将 lastLastItem 声明为 Activity 中的字段。 lastItem 只不过是您的 lasinscren。【参考方案2】:一个简单的方法是定义一个布尔参数:
if(view.getLastVisiblePosition() == totalItemCount-1 && isLoadMore)
isLoadMore = false;
pageNum++;
loadMoreData(searchStr, donViID, pageNum, Constant.RECORD_PER_PAGE);
【讨论】:
以上是关于在滚动侦听器上调用 asynctask 三次或多次在 listview 上滚动一次的主要内容,如果未能解决你的问题,请参考以下文章
登录表单在第一次尝试在实时服务器上失败,但在第二次或第三次尝试
Android:我在哪里可以在服务中实现 socket.on(...)?我多次收到相同的消息
数据更改 SwiftUI 时多次调用 Firebase 侦听器