gpt4 book ai didi

Android AsyncTask 在方向更改时阻止 UI

转载 作者:行者123 更新时间:2023-11-30 04:44:49 25 4
gpt4 key购买 nike

我有一个很奇怪的问题。我有一个 AsyncTask,它在我旋转手机时似乎会阻塞 UI 线程。

首先,让我声明,我对我的 Activity 被销毁并在旋转时重新创建感到满意。我将 AsyncTask 保存在 onRetainNonConfigurationInstance() 中,在 onDestroy() 中将 Activity 与它分离,然后在 onCreate( ) 使用 getLastNonConfigurationInstance()

这一切都很好,只要 AsyncTask 没有做繁重的工作。例如,为了调试我的问题,我有这个,它完全按预期工作,没有 UI 阻塞:

@Override
protected Boolean doInBackground(Void... params) {
boolean success = false;
final DbAdapter dbAdapter = dbService.getAdapter();

try {
// pretend to do some complicated work
Thread.sleep(20000);
success = true;
} catch (Exception e) {
e.printStackTrace();
}

return success;
}

但是,如果我将其更改为在后台执行一些实际工作,那么在调用 onPause() 开始旋转和调用 onResume() 之间会有很长的延迟 稍后在新方向中被调用。此延迟为数十秒,在此期间 UI 处于不一致状态(旧布局以新方向裁剪)并且似乎旋转在 AsyncTask 上阻塞。唯一的变化是 try block 中的两行:

@Override
protected Boolean doInBackground(Void... params) {
boolean success = false;
final DbAdapter dbAdapter = dbService.getAdapter();

try {
// actually do some complicated work
XmlParser parser = new XmlParser(context, dbAdapter);
success = parser.parse(source);
} catch (Exception e) {
e.printStackTrace();
}

return success;
}

context 是传递给 AsyncTask 构造函数的全局应用程序上下文,所以我不认为我不小心保留了对传出 Activity

还有什么可能出错?

最佳答案

可能您的 Activity 也在尝试使用 dbAdapter,并且您进行了适当的同步以防止两个线程同时使用 dbAdapter

可能您的 Activity 正试图在主应用程序线程上从文件系统加载内容,而您的数据库操作导致了过多的争用。在硬件上,YAFFS2 对于 I/O 操作实际上是单线程的。

您可以使用 Traceview 尝试获取更多有关占用您时间的信息,并且您可以在 Android 2.2 及更高版本上使用 StrictMode 来查看您的 Activity 可能在何处尝试执行文件 I/O 在主应用程序线程上。

此外,如果您的 AsyncTask 正在将 XML 转换为数据库条目,那么使用 IntentService 可能比 AsyncTask 更好。

关于Android AsyncTask 在方向更改时阻止 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5240145/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com