Asynctask使用产生bug

Question:最近在项目中出现了偶现的bug,打开详情页面会白屏,只要出现了一次白屏,退出在打开别的文章详情页都是白屏的状态。

解决问题:Android项目中只要可以复现的bug基本上都能通过打断点进行解决(吹个皮)。可是这个问题是偶现的而且机率极小,于是开始排查问题。
怀疑的问题点:

  1. 加载文章内容的接口出了问题
    对出现bug的手机进行抓包,发现加载文章内容的接口没有任何问题
  2. 加载内容的时候内容已经加载完成,但是没有显示出来
    进过排查设置view可见与不可见的地方没有任何问题。
  3. 顺理成章的怀疑用webview加载内容的时候,内容根本就没有处理好
    最后才发现请求完文章内容接口之后,为了达到详情页秒开的目的,将文章页的html内容在本地进行了组装。这个组装的过程是个异步处理的过程,好死不死的用到了AsyncTask,最后也就是这个地方出现了问题

AsyncTask就是Google官方提供的一个异步线程处理,ui线程更新的很好的handler+thread的封装类,方便开发者使用起来比较方便,具体的使用方式自行Google。我现在想说的是Asynctask串行和并行的问题。

在执行Asynctask任务的时候,系统提供了两个运行方式。

 htmlParserTaskTask.execute();
 htmlParserTaskTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

在介绍这两个方法的差异之前,先说明两个AsyncTask里面的Executor

    private static class SerialExecutor implements Executor {
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;

        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                   //上一个任务执行完才能去执行下一个任务串行执行
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }

        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }


    public static final Executor THREAD_POOL_EXECUTOR;

    static {
    //线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }
  • execute()
    当你通过这个方式去执行任务的时候,默认的任务执行器就是SerialExecutor,串行执行任务,one by one。

-executeOnExecutor()
当你通过这个方式去执行任务的时候,这个时候是并行执行任务的。使用的任务执行器就是线程池了。

了解这些基本知识之后,去解决问题
问题的点在与这个Asynctask没有执行,你点开的文章的处理内容的Asynctask没有执行。因为是串行的执行任务。有的人会说将里面执行的方式改为并行不就行了吗,我现在只能告诉你是不行的,这个方式用起来还是有一定的风险,并不能保证百分百的去触发。所以在项目中我把AsyncTask进行废弃了,项目中采用的是Rxjava+Retrofit+MVP,于是我采用了Rxjava进行处理,之后就没有任务白屏的出现。

Asyncatask有的时候比较坑,能不用就不用这个玩意吧,还说一句题外话,AsyncTask和极光推送有冲突
Asynctask使用产生bug_第1张图片

你可能感兴趣的:(Asynctask)