`
lynen
  • 浏览: 128518 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

Asynctask onPostExecute未执行的问题分析

 
阅读更多

问题现象:

app使用Asynctask从网络下载数据,并将数据同步更新到UI上进行显示。

在app使用的过程中,偶尔会出现数据未更新的情况,且这个问题现象一时找不到必现的操作方法

跟踪问题原因发现是AsyncTask.onPostExecute未被执行到的原因。

 

问题解决办法:

google之后,发现可以通过如下方法解决问题:

在app的application中的onCreate方法中增加如下代码

 

try {
			Class.forName("android.os.AsyncTask");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

 

 问题的解决办法可以查看如下链接的一些说明:

1.http://code.google.com/p/android/issues/detail?id=20915

2.http://stackoverflow.com/questions/4280330/onpostexecute-not-being-called-in-asynctask-handler-runtime-exception

 

问题原因:

AsyncTask有如下代码:

 

private static final InternalHandler sHandler = new InternalHandler();

 

 此处的InternalHandler extends Handler,且使用默认的构造函数。

看Handler的默认构造函数如下:

 

public Handler() {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = null;
    }

 

 问题原因的关键分析点在于

 

mLooper = Looper.myLooper();

 

也就是说,使用Handler使用默认的构造函数的话,Handler使用的Looper是Looper中如下函数返回的内容:

 

public static final Looper myLooper() {
        return (Looper)sThreadLocal.get();
    }

以上种种,可以查看依次查看AsyncTask-->>Handler-->>Looper-->>TreadLocal的源代码自行理解。

在以上内容分析完毕后,搜索app中AsyncTask的使用场景,发现在不同的使用场景中,有一处场景在使用AsyncTask之前有如下代码

 

Looper myLooper = Looper.myLooper();
                            if (myLooper == null) {

                                Looper.prepare();
                            }

 找到以上代码后,也就分析出了问题重现的方式

 

 

问题结论:

1.使用AsyncTask的时候要谨慎使用Looper

分享到:
评论

相关推荐

    android中AsyncTask的用法

    在Android应用开发中,AsyncTask是一个用于在后台线程执行耗时操作并更新UI的工具类,它是Android 1.5版本引入的。AsyncTask的设计初衷是为了简化异步编程,避免直接操作线程和Handler带来的复杂性。下面我们将详细...

    AsyncTask类实例详解

    最后,从Android 3.0(API Level 11)开始,AsyncTask的执行策略有所改变,不再保证所有的任务都会在同一线程中执行,而是采用了串行执行的方式,以避免过多的并发导致的问题。而在Android 9.0(API Level 28)之后...

    Android AsyncTask 源码解析

    AsyncTask 是 Android 平台上一个非常重要的工具类,用于在后台线程执行耗时操作,然后在 UI 线程更新结果,从而避免了因长时间运行任务而导致的 ANR(Application Not Responding)错误。在深入探讨 AsyncTask 的...

    android任务后台处理 asyncTask封装

    此外,从Android 3.0(API级别11)开始,`AsyncTask`的执行策略有所改变,多个相同`AsyncTask`实例可能会并发执行,而非按顺序执行,因此在高版本Android中应特别注意这一点。 总的来说,`AsyncTask`是Android...

    Android中异步类AsyncTask用法总结

    AsyncTask 是 Android 平台上一种轻量级的异步处理机制,主要用于在后台执行耗时操作,同时确保结果能够在主线程中安全地更新 UI。它简化了多线程编程,尤其是与用户界面交互的需求。 首先,AsyncTask 包含三个泛型...

    AsyncTask用法

    AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不... onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

    AsyncTask练习demo

    AsyncTask是Android中一个用于在后台线程执行耗时操作并更新UI的工具类,它非常适合处理轻量级的异步任务。在这个"AsyncTask练习demo"中,我们可以深入理解和学习如何有效地使用AsyncTask。 首先,AsyncTask有三个...

    01_AsyncTask_演示线程阻塞

    `AsyncTask`是Android提供的一种轻量级的异步任务处理框架,它允许开发者在后台线程执行耗时操作,然后在UI线程更新结果,避免了阻塞主线程导致的ANR(Application Not Responding)问题。这篇我们将深入探讨`...

    android asyncTask

    从Android 3.0(API Level 11)开始,`AsyncTask`默认是在一个单线程池中执行,这可能导致任务顺序执行而非并行。为了解决这个问题,开发者可以选择自定义线程池或者使用其他异步处理框架,如`Handler`、`Loader`、`...

    异步任务AsyncTask

    在Android开发中,异步任务(AsyncTask)是一种常见的处理耗时操作的方式,尤其是在主线程中需要执行网络请求、数据库操作或大型数据处理时。它能够避免UI线程被阻塞,提供更好的用户体验。让我们深入了解一下`...

    封装AsyncTask

    AsyncTask是Android开发中用于在UI线程之外执行耗时操作的一种工具,它允许开发者在后台线程中执行任务,并在完成后更新UI。在Android应用中,由于主线程(UI线程)负责处理用户交互,如果在此线程上执行耗时操作,...

    Android 线程AsyncTask逐步在list中加入条目

    注意,`AsyncTask`的实例是单线程的,意味着同一时间只能有一个`AsyncTask`实例在执行。如果你需要同时执行多个任务,可以考虑其他并发模型,如`IntentService`或`ExecutorService`。 总之,通过这个例子,新手可以...

    Android AsyncTask异步处理下载网页

    Android提供了一种便捷的机制,名为`AsyncTask`,用于在后台线程执行这些任务,同时允许在主线程更新UI。`AsyncTask`是一个轻量级的框架,设计用来简化在Android应用程序中进行后台操作的过程。 `AsyncTask`包含三...

    AsyncTask结合HttpUrlConnection的例子

    `AsyncTask`是Android提供的轻量级异步任务框架,它允许开发者在后台线程执行耗时操作,并在主线程更新UI。`AsyncTask`包含三个泛型参数:`Params`、`Progress`和`Result`,分别代表输入参数类型、进度类型和返回...

    异步操作类AsyncTask

    其次,由于`AsyncTask`的执行队列限制,同一时间只能有三个任务处于活动状态,这可能导致并发问题。为了解决这些问题,开发者可能需要考虑使用其他的异步处理工具,如`ExecutorService`、`Handler`或`LiveData`。 `...

    AsyncTask之cancel操作

    在Android开发中,AsyncTask是一个常用的工具类,用于在后台线程执行耗时操作,并在UI线程更新结果。本文将深入探讨`AsyncTask`的`cancel`操作,结合提供的链接文章《AsyncTask中cancel方法的误读》进行详细解析。 ...

    Android异步请求之AsyncTask

    在使用`AsyncTask`时,需要考虑兼容性问题。 4. **内存管理**:`AsyncTask`的实例不应被静态引用,因为这可能导致Activity无法正常销毁。 5. **取消任务**:通过`cancel(true)`方法可以尝试取消正在执行的任务,但...

    AsyncTask使用及源码解析

    此外,Android的AsyncTask有版本差异,从Android 3.0(API级别11)开始,AsyncTask默认改为单线程模式,避免了并发执行导致的问题,但在处理大量并发任务时,可能会降低性能。因此,在处理大量并发任务时,开发者...

    AsyncTask小练习

    为了解决这个问题,Android提供了AsyncTask,它能方便地在线程池中执行后台任务,并在完成后更新UI。 AsyncTask包含三个泛型参数,分别代表了三个步骤的数据类型: 1. `Params`:表示在后台任务执行前可以输入的...

    AndEngine_分析之三-----AsyncTask_BaseActivity备忘

    ### AndEngine分析之三——AsyncTask与BaseActivity深入解析 #### 一、AsyncTask概述 在AndEngine项目中,为了实现界面更新等操作时避免主线程阻塞的问题,使用了`AsyncTask`来处理后台任务。`AsyncTask`提供了一...

Global site tag (gtag.js) - Google Analytics