当在onPostExecute中更新UI的AsyncTask正在运行时,操作UI将导致ANR

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当在onPostExecute中更新UI的AsyncTask正在运行时,操作UI将导致ANR相关的知识,希望对你有一定的参考价值。

这是我的代码:

AsyncTCPReqTaskCommon task = new AsyncTCPReqTaskCommon(ip, port, new 
TCPReqCallBackCommon() {
   @Override
   public void onReceiveSuccess(String result{
       tvText.setText(result);
   }

   @Override
   public void onReceiveFailure() {
   }
});

task.execute(sendCmd);

onReceiveSuccess将在onPostExecute召唤。异步网络请求需要3~4秒。当异步任务正在运行时,滑动UI将导致ANR。当我注释掉这条线tvText.setText(result);时,ANR将不会出现。

异步任务没有在UI线程中运行,为什么会出现ANR?更新TextView的正确方法是什么?提前致谢!

我的用户界面不支持幻灯片。 XML:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mobile.mytestapp.MainActivity">

<TextView
    android:id="@+id/tvText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:layout_gravity="center_horizontal"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="ReqNet"
    android:onClick="ReqNet"/>

</LinearLayout>

一些日志:

03-05 14:33:47.108 12255-12266/com.mobile.mytestapp W/art: Suspending all threads took: 7.100ms
03-05 14:33:47.111 12255-12266/com.mobile.mytestapp I/art: Background sticky concurrent mark sweep GC freed 6(384B) AllocSpace objects, 0(0B) LOS objects, 0% free, 14MB/14MB, paused 9.179ms total 34.364ms
03-05 14:33:59.773 12255-12255/com.mobile.mytestapp I/Choreographer: Skipped 762 frames!  The application may be doing too much work on its main thread.
答案

感谢大家。我想我找到了原因。在我的AsyncTCPReqTaskCommon中,我从堆中新建一个1M缓冲区以接收网络响应。在网络操作之后,导致GC,它将锁定变量tvText。这个GC花了太长时间,“tvText.setText(结果);”无法执行。所以,ANR出现了!我试过减小缓冲区大小,ANR没有出现!

以上是关于当在onPostExecute中更新UI的AsyncTask正在运行时,操作UI将导致ANR的主要内容,如果未能解决你的问题,请参考以下文章

从 onPostExecute(String result) 开始活动不设置 ui 标志

onPreExecute() 和 onPostExecute() 是在 UI 线程还是在启动 AsyncTask 的线程上执行?

AsyncTask doinbackground onProgressUpdate onCancelled onPostExecute的基本使用

在 AsyncTask 的 onPostExecute 之后,无法按意图更新 RecyclerView

如何使用 AsyncTask 的 onPostExecute 方法更新 Android 中的变量

在 Asynctask 的 onPostExecute() 方法中更改片段