当在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