在完成之前取消列表视图适配器的异步任务

Posted

技术标签:

【中文标题】在完成之前取消列表视图适配器的异步任务【英文标题】:Cancelling asynctask for list view adapter before its finished 【发布时间】:2015-08-12 03:06:07 【问题描述】:

我需要在完成之前通过按返回按钮取消填充列表视图适配器的异步任务。通过这段代码

@Override
public View getView(final int position, View convertView, ViewGroup parent) 

    if(convertView==null)
        LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);convertView=inflater.inflate(R.layout.seatadapter, null);

         TextView text3=(TextView)convertView.findViewById(R.id.text3);
         ProgressBar progressBar1=(ProgressBar)convertView.findViewById(R.id.progressBar1);
         TextView predic=(TextView)convertView.findViewById(R.id.textView3);
         TextView classs=(TextView)convertView.findViewById(R.id.textView4);
         ImageView img1=(ImageView)convertView.findViewById(R.id.imageView1);

new update(classs,predic, text3, progressBar1,img1).execute(tarinname.get(position), Date.get(position), Ffrom.get(position), Tto.get(position), Ccl.get(position));

class update extends AsyncTask

@Override
        protected Object doInBackground(Object... params) 

Code For Json Parsing....

        protected void onPostExecute(Object result) 
            super.onPostExecute(result);

            if (this.result.contains("CurrentStatus")) 
                 progressBar.setVisibility(progressBar.GONE);

                 t.setVisibility(t.VISIBLE);
                 t3.setVisibility(t3.VISIBLE);
                im1.setVisibility(im1.VISIBLE);

                 t3.setText("Class "+TravelClass);

                 t1.setText(perdcition);

                 if (ConfirmTktStatus.contains("Confirm")) 
                    im1.setImageResource(R.drawable.img_green);

                
                 if (ConfirmTktStatus.contains("Probable")) 

                    
                 if (ConfirmTktStatus.contains("No Chance")) 

                    

                t.setText(var1);

            else 
                 progressBar.setVisibility(progressBar.GONE);
            


                Toast.makeText(context, var, Toast.LENGTH_LONG).show();
                

这是适配器类,我们无法在其过程中通过按返回按钮来取消它。按下后退按钮时,活动关闭,但后台任务继续。

@Override
            protected void onCancelled() 
                // TODO Auto-generated method stub
                super.onCancelled();
                ((Activity)context).finish();

            

我已经试过了,但没用..!!

【问题讨论】:

cancelmetod 怎么样? 更新我尝试过的问题..!! 看看你在做什么:当任务被取消时你完成了活动。您应该在活动完成时取消任务。您应该将 AsynkTask 实例保存在某个变量中,并在活动 onStop 生命周期回调中取消它。 【参考方案1】:

请创建一个列表来存储当前的 AsyncTask,然后随时取消它

for (AsyncTask myAsyncTask : myAsyncTasks) 
    if (myAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING)) 
        myAsyncTask.cancel(true);
    

myAsyncTasks.clear();

您的代码的详细信息:

private List<AsyncTask> myAsyncTasks = new ArrayList<>();
public void addRunningTask(AsyncTask task) 
    myAsyncTasks.add(task);


public void cancelRunningTasks() 
    for (AsyncTask myAsyncTask : myAsyncTasks) 
        if (myAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING)) 
            myAsyncTask.cancel(true);
        
    
    myAsyncTasks.clear();

@Override
public void onBackPressed() 
    cancelRunningTasks();

@Override
public View getView(final int position, View convertView, ViewGroup parent) 

    if(convertView==null)
        LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);convertView=inflater.inflate(R.layout.seatadapter, null);

         TextView text3=(TextView)convertView.findViewById(R.id.text3);
         ProgressBar progressBar1=(ProgressBar)convertView.findViewById(R.id.progressBar1);
         TextView predic=(TextView)convertView.findViewById(R.id.textView3);
         TextView classs=(TextView)convertView.findViewById(R.id.textView4);
         ImageView img1=(ImageView)convertView.findViewById(R.id.imageView1);

AsyncTask task = new update(classs,predic, text3, progressBar1,img1);
task.execute(tarinname.get(position), Date.get(position), Ffrom.get(position), Tto.get(position), Ccl.get(position));
addRunningTask(task);

class update extends AsyncTask

@Override
        protected Object doInBackground(Object... params) 

Code For Json Parsing....

        protected void onPostExecute(Object result) 
            super.onPostExecute(result);

            if (this.result.contains("CurrentStatus")) 
                 progressBar.setVisibility(progressBar.GONE);

                 t.setVisibility(t.VISIBLE);
                 t3.setVisibility(t3.VISIBLE);
                im1.setVisibility(im1.VISIBLE);

                 t3.setText("Class "+TravelClass);

                 t1.setText(perdcition);

                 if (ConfirmTktStatus.contains("Confirm")) 
                    im1.setImageResource(R.drawable.img_green);

                
                 if (ConfirmTktStatus.contains("Probable")) 

                    
                 if (ConfirmTktStatus.contains("No Chance")) 

                    

                t.setText(var1);

            else 
                 progressBar.setVisibility(progressBar.GONE);
            


                Toast.makeText(context, var, Toast.LENGTH_LONG).show();
                

【讨论】:

我把这段代码放在哪里..??在 doInBackGround 或其他地方..??我将它粘贴在适配器中..!! 首先,您应该通过以下方式将任务插入列表: AsyncTask task = new update(classs,predic, text3, progressBar1,img1)); task.execute...;myAsyncTasks.add(task);然后在按下返回按钮时取消它们 初始化数组列表,“update”是异步任务类名 ArrayList upd;定义了数组列表 upd=new ArrayList();新的更新(类,预测,文本3,progressBar1,img1)。执行(tarinname.get(位置),日期.get(位置),Ffrom.get(位置),Tto.get(位置),Ccl.get(位置) ); @Override protected Object doInBackground(Object... params) for (AsyncTask myAsyncTask : upd) if (myAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING)) myAsyncTask.cancel(true); upd.clear(); 您为 2 个方法创建了一个 Util 类:插入到 myAsyncTasks 和取消 myAsyncTasks 中的任务。像这样: private static List myAsyncTasks = new ArrayList(); public static void addRunningTask(AsyncTask task) myAsyncTasks.add(task); public static void cancelRunningTasks() for (AsyncTask myAsyncTask : myAsyncTasks) if (myAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING)) myAsyncTask.cancel(true); myAsyncTasks.clear(); 感谢您的代码,但出现了一些错误,例如 IDE 迫使我删除器覆盖背压方法,因为它不能在适配器中使用..!

以上是关于在完成之前取消列表视图适配器的异步任务的主要内容,如果未能解决你的问题,请参考以下文章

我如何知道取消的异步任务是不是完成?

如何从客户端取消异步任务

如何在 Android 中使用异步任务通过数组列表更新列表视图?

如何确保两个“开始”的异步任务在运行另一个任务之前完成?

如何取消 useEffect 清理函数中的所有订阅和异步任务?

使用异步任务时光标变为空?