AsycnTask

(1)作用:

1、执行耗时操作

2、实现工作线程与主线程之间的通信

(2)示例:

public class MainActivity extends AppCompatActivity {
    private Button mBtStart;
    private TextView mTvProgress;
    private ProgressBar mProgress;
    private Button mCencele;

    //线程
    private MyAsyncTask mAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtStart = (Button) findViewById(R.id.bt_start);
        mTvProgress = (TextView) findViewById(R.id.tv_progress);
        mProgress = (ProgressBar) findViewById(R.id.progress);
        mCencele = (Button) findViewById(R.id.cencele);

        mAsyncTask=new MyAsyncTask();

        //开始
        mBtStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mAsyncTask.execute();
            }
        });

        //取消
        mCencele.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //取消一个正在执行的任务,这是会调用到onCancelled()
                mAsyncTask.cancel(true);
            }
        });

    }


    //参数为3种泛型类型
    //整体的作用:控制AsyncTask子类执行线程任务时各个阶段的返回类型
    //参数1、Params:开始异步任务执行时传入的参数类型,对应excute()中传递的参数
    //参数2、Progress:异步任务执行过程中,返回下载进度值的类型
    //参数3、Result:异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致

    private class MyAsyncTask extends AsyncTask<String,Integer,String>{

        //作用:执行线程任务前的操作,用于界面的初始化,如显示进度条的对话框
        @Override
        protected void onPreExecute() {
            mTvProgress.setText("加载中");
        }

        //作用:接收输入的参数、执行任务中的耗时操作,返回 线程任务执行的结果
        @Override
        protected String doInBackground(String... strings) {

            int count=0;
            int add=1;
            while (count<99){
                count+=add;

                //调用publishProgress()显示进度条,之后将执行onProgressUpdate()
                publishProgress(count);

                try {
                    //模拟耗时操作,休眠1秒
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        //作用:在主线程 显示线程任务执行的进度
        @Override
        protected void onProgressUpdate(Integer... values) {
            mProgress.setProgress(values[0]);
            mTvProgress.setText("当前加载的进度。。。"+values[0]+"%");
        }

        //作用:接收线程任务执行结果、将执行结果显示到UI组件
        @Override
        protected void onPostExecute(String s) {
            //执行完成,更新UI
            mTvProgress.setText("加载完成");
        }

        //作用:将异步任务设置成取消状态
        @Override
        protected void onCancelled() {
            mTvProgress.setText("已经取消");
        }
    }

    @Override
    protected void onDestroy() {
        mAsyncTask.cancel(true);
        super.onDestroy();
    }
}
运行结果:


当再次点击加载数据时会报错:


(3)方法的执行顺序:
基本使用:execute > onPreExecute > doInBackground > onPostExecute
显示进度:execute > onPreExecute > doInBackground > publishProgress() > onPostExecute > onProgressUpdate 
执行线程任务时终止:execute > onPreExecute > doInBackground > onCancelled

(4)注意:
1、执行execute(Params... params),必须在UI线程中调用。同一个AsyncTask示例对象只能执行1次,若执行2次就会抛出异常。
2、因为AsyncTask不与任何组件绑定生命周期,所以在Activity或者Fragment中的 onDestory() 调用 cancel()。
3、内存泄漏。若As云南菜Task被声明为Activity的非静态内部类当Activity被销毁的时,会因为AsyncTask保留对Activity的引用导致Activity无法被回收,最终引起内存泄漏。所以使用AsyncTask时,AsyncTask被声明为Activity的静态内部类。
4、线程任务结果丢失:当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()
将不生效,即无法更新UI操作。所以,在Activity恢复时的对应方法 重启 任务线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值