当前位置:   article > 正文

AsyncTask的使用及弊端_asynctask使用在哪些场景?它的缺陷是什么?如何解决?

asynctask使用在哪些场景?它的缺陷是什么?如何解决?

(一)介绍

       1,AsyncTask,是一种轻量级的异步任务类,内部封装了Handler和Thread,可以方便的将子线程的数据传递到UI线程并更新UI.但它不适合进行特别耗时的任务,对于特别耗时的任务,建议使用线程池.

      

 

(一)关键api

1,三个参数:Params,Progress,Result,如果AsyncTask确定不需要传递具体参数,那么这三个泛型参数可以用Void来代替。

    A,Params,表示参数的类型

    B,Progress,表示后台任务执行的进度的类型

    C,Result,后台任务返回结果的类型

 

2,四个参数:

onPreExcute(),DoInBackGround(),onProgressUpdate(),onPostExcute();

A,onPreExcute(),在主线程中执行,在异步任务之前调用,一般可以用于做任务前的准备,比如进度圈的显示.

B,DoInBackGround(),在线程池中执行,用于处理一些耗时任务.通过publishProgress()将进度发布出去.然后通过return将结果返回出去.

C,onProgressUpdate(),在主线程中执行,获取任务的最新进度.

D,onPostExcute(),在主线程中执行,用于接收异步任务的结果.

     E,onCancelled(),它同样在主线程中执行,当异步任务取消时,onCancelled()会被调用,这个时候onPostExecute()则不会被调用,但是要注意的是,AsyncTask中的cancel()方法并不是真正去取消任务,只是设置这个任务为取消状态,我们需要在doInBackground()判断终止任务。就好比想要终止一个线程,调用interrupt()方法,只是进行标记为中断,需要在线程内部进行标记判断然后中断线程。


)

 

(三)代码使用:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mProgressDialog = new ProgressDialog(this);
    new DownloadTask().execute();
}

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
    @Override
    protected void onPreExecute() {
        mProgressDialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            while (true) {
                int downloadPercent = doDownload();
                publishProgress(downloadPercent);
                
                if (downloadPercent >= 100) {
                    break;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }



    @Override
    protected void onProgressUpdate(Integer... values) {
        mProgressDialog.setMessage("当前下载进度:" + values[0] + "%");
    }

    @Override
    protected void onPostExecute(Boolean result) {
        mProgressDialog.dismiss();
        if (result) {
            Toast.makeText(ActivityA.this, "下载成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(ActivityA.this, "下载失败", Toast.LENGTH_SHORT).show();
        }
    }
}

 

 

(四)注意事项:

1,一个AsyncTask对象只能创建一次,也就是说只能调用一次excute()方法,否则会报运行时异常.

2,AsyncTask必须在主线程中创建,在主线程中加载.

 

(五)弊端:

 

    1,生命周期

    AsyncTask不与任何组件绑定生命周期,所以在Activity/或者Fragment中创建执行AsyncTask时,最好在Activity/Fragment的onDestory()调用 cancel(boolean);

    2.内存泄漏

    如果AsyncTask被声明为Activity的非静态的内部类,那么AsyncTask会保留一个对创建了AsyncTask的Activity的引用。如果Activity已经被销毁,AsyncTask的后台线程还在执行,它将继续在内存里保留这个引用,导致Activity无法被回收,引起内存泄露。

    3. 结果丢失

    屏幕旋转或Activity在后台被系统杀掉等情况会导致Activity的重新创建,之前运行的AsyncTask(非静态的内部类)会持有一个之前Activity的引用,这个引用已经无效,这时调用onPostExecute()再去更新界面将不再生效。

 

(六),原理

        Android3.0开始,AsyncTask默认采用串行执行.若是想并行执行,只需调用executeOnExecutor方法,并传入THREAD_POOL_EXECUTOR作为其线程池即可。(在不同版本的模拟器就可以测出)

         AsyncTask有2个线程池:SerialExcutor和THREAD_POOL_EXCUTOR,SerialExcutor是用于排队的,而THREAD_POOL_EXCUTOR才是真正执行任务的.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/555089
推荐阅读
相关标签
  

闽ICP备14008679号