zoukankan      html  css  js  c++  java
  • Asynctask onPostExecute未执行的问题分析

    问题现象:
    app使用Asynctask从网络下载数据,并将数据同步更新到UI上进行显示。
    在app使用的过程中,偶尔会出现数据未更新的情况,且这个问题现象一时找不到必现的操作方法
    跟踪问题原因发现是AsyncTask.onPostExecute未被执行到的原因。

    问题解决办法:
    google之后,发现可以通过如下方法解决问题:
    在app的application中的onCreate方法中增加如下代码

    1 [mw_shl_code=java,true]try {
    2                         Class.forName("android.os.AsyncTask");
    3                 } catch (ClassNotFoundException e) {
    4                         e.printStackTrace();
    5                 }[/mw_shl_code]

    问题的解决办法可以查看如下链接的一些说明:
    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有如下代码:

    [mw_shl_code=java,true]private static final InternalHandler sHandler = new InternalHandler();[/mw_shl_code]

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

     1 [mw_shl_code=java,true]public Handler() {
     2         if (FIND_POTENTIAL_LEAKS) {
     3             final Class<? extends Handler> klass = getClass();
     4             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
     5                     (klass.getModifiers() & Modifier.STATIC) == 0) {
     6                 Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
     7                     klass.getCanonicalName());
     8             }
     9         }
    10 
    11         mLooper = Looper.myLooper();
    12         if (mLooper == null) {
    13             throw new RuntimeException(
    14                 "Can't create handler inside thread that has not called Looper.prepare()");
    15         }
    16         mQueue = mLooper.mQueue;
    17         mCallback = null;
    18     }[/mw_shl_code]


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

    mLooper = Looper.myLooper();

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

    1 [mw_shl_code=java,true]public static final Looper myLooper() {
    2         return (Looper)sThreadLocal.get();
    3     }[/mw_shl_code]


    以上种种,可以查看依次查看AsyncTask-->>Handler-->>Looper-->>TreadLocal的源代码自行理解。
    在以上内容分析完毕后,搜索app中AsyncTask的使用场景,发现在不同的使用场景中,有一处场景在使用AsyncTask之前有如下代码

    1 [mw_shl_code=java,true]Looper myLooper = Looper.myLooper();
    2                             if (myLooper == null) {
    3 
    4                                 Looper.prepare();
    5                             }[/mw_shl_code]


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

  • 相关阅读:
    2012 regional 。。
    joj2443
    java笔记代码实现汉诺塔移动过程和移动次数
    java笔记增加虚拟机内存
    java笔记修改javadoc为中文API信息
    java笔记String类格式化当天日期转换符文档
    java笔记正则表达式的运用(包括电话,邮箱验证等)
    java笔记String类对象解析与运用
    Java笔记IO流的运用
    java笔记BigDecimal的使用
  • 原文地址:https://www.cnblogs.com/xuanyuanzhuo-blog/p/3976055.html
Copyright © 2011-2022 走看看