Android之AsyncTask(二)

前言:

         其实我不太敢写这篇文章,因为里面为了达成目的,用了一些不是很好的方法。

正文:

        如果你正在用AsyncTask写一个下载东西的功能,那么也可能需要取消下载。知道AsyncTask的应该都知道其自带了onCancelled()方法,但是呢,onCncelled只能取消执行onPostExecute方法,而不能取消doInBackground。所以呢,为了达到目的,我得多作几步处理,中心思想如下。

      首先,我们得声明一个标记callFinish来告诉线程,该结束doInBackground了。

      其次,当事件触发取消的时候,将callFinish标记为true。

      接着,调用cancel(true)方法,但不能取消doInbackground。

     最后,再执行一边doInbackground,由于callFinish为true,所以可以直接进入onPostExecute。

     当然了,为了避免onPostExecute中结果的混淆,我们可以设置另外一个bool标记,让用户区分哪一个结果值是正常的,哪一个是不正常的(正常?不正常?语言表述有问题,呵呵,意会就行!)。

     好了,上代码。


     (1)初始化:

    boolean callFinish = false;

   HelloWorld mHelloWorld = new HelloWorld();


   (2)HelloWorld:  

    public class HelloWorld extends AsyncTask<Object, Object,Object> {

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

        boolean download = false;

       do{        

         <处理数据>

        download = true;

         callFinish = true; //处理结束后赋值为true

        }while(!callFinish);

        returndownload;

   }


        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result) {
                Toast.makeText(mContext,
                         "下载成功",
                        Toast.LENGTH_SHORT).show();
            }else{

                  Toast.makeText(mContext,
                         "取消下载",
                        Toast.LENGTH_SHORT).show();

            }
        }


          @Override
        protected void onCancelled() {
            super.onCancelled();
            execFinish();
        }


 }


    (3)下达取消指令:

    public void cancelDownLoad() {
        execFinish();
        Toast.makeText(mContext, “停止下载”,
                Toast.LENGTH_SHORT).show();
    }

    private void execFinish() {
        callFinish = true;
        
mHelloWorld.cancel(true);
        
mHelloWorld.execute(-2);//不一定要写-2
    }


     以上便是不择手段地下达取消指令的中心思想。接下来要说的是处理超时的手段。很多情况下,数据请求有一个最大请求时间,因为进度条一直这么不断地转啊转啊也会让用户不爽。

     设置数据请求的超时时间很简单,就是在执行的同时再起一个线程,当到达超时时间后,发现数据处理还是没有完成,那么就会进行其他操作,这里,姐的手段比较狠,超时了,姐就cancel掉它,当然也有人缓和一点,弄点别的啥,因项目情况而议吧。看代码就明了了。


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if(alertDialog!= null && !alertDialog.isShowing()){
          alertDialog.show();
       }
          
            m.start(); //另起的线程在这里!!!不一定要放这里哦,其他地方也行,只要能执行到。。

        //  不想用m.start()也行,直接用

       // mHandler.postDelayed(new Runnable() {
            
      //     @Override
      //     public void run() {
                
                
       //     }
      //  }, 18000);

     //也可以,但我喜欢用前者,维护性和扩展性都好,唉。。。深受需求变更毒害的娃儿伤不起啊。

     
        }
    }

    private Thread m = new Thread(new Runnable() {
       
       @Override
        public void run() {
           
            try {

                m.sleep(18000); //睡个18秒再执行。。。话说10秒就是姐等待的极限了。

                mHandler.sendEmptyMessage(0);


            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
           
       }
    });

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(android.os.Message msg) {
            if(alertDialog!=null&&alertDialog.isShowing()){
                alertDialog.dismiss();

               cancelDownLoad();


            }
           
        }
    };

   

    好了,讲完取消AsyncTask和超时处理,现在该讲讲一些注意事项了。其实也没啥太多注意事项,就两点。

   1.不能在doInBackground中做任何UI方面的操作,什么setText啊,Toast啊,一律别用,要用就交给Handler。

   2.AsyncTask会自动结束自己的线程,所以不要费心去关闭线程。其他类型的线程用完了可要关掉哦!

 

       另外一种异步线程,将在下一篇中介绍。Looper+Thread!





       



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值