在滚动侦听器上调用 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 侦听器

使用单个侦听器多次调用 DatePicker

如何通过jQuery检查div类是不是存在三次或更多? [复制]

在python中查找字符串中出现字符串的第二次,第三次或更多次[重复]