【发布时间】:2020-02-27 00:54:23
【问题描述】:
我在我的应用程序中使用ASyncTask 通过 REST API 从 Web 服务 (Bitly) 获取一些数据(短 URL)。
当ASyncTask 完成时,我想将结果传回我的MainActivity。
使用AsyncTask 的onPostExecute 方法可以将数据返回到MainActivity。
我已经阅读并阅读了有关如何执行此操作的信息,似乎有两种通用方法。
最初我使用的是“WeakReference”方法,即在 AsyncTask 类的开头创建对 MainActivity 的弱引用,如下所示:
private class getShortURL extends AsyncTask<String, Void, String> {
private WeakReference<MainActivity> mainActivityWeakReference;
myASyncTask(MainActivity activity) {
mainActivityWeakReference = new WeakReference<>(activity);
}
{etc etc}
使用这种方法,您的 AsyncTask 类位于您的 MainActivity 类之外,因此需要通过弱引用来引用很多东西。
这工作得很好(除了我怀疑——可能是错误的——这个弱引用可能是偶尔出现 NPE 的原因),但后来我找到了另一种做事方式。
第二种方法涉及将ASyncTask 类移动到MainActivity 类中。
通过这种方式,我能够直接访问 MainActivity 类中可访问的所有内容,包括在 MainActivity 中定义的 UI 元素和方法。这也意味着我可以访问字符串等资源,并且可以生成toasts 来告知用户正在发生的事情。
在这种情况下,可以删除上面的整个 WeakReference 代码,并且可以将 AsyncTask 类设为私有。
然后我也可以直接在onPostExecute 中执行此类操作,或者将其保存在MainActivity 中的一个方法中,我可以直接从onPostExecute 调用:
缩短进度条.setIndeterminate(false);
short_progress_bar.setVisibility(View.INVISIBLE);
if (!shortURL.equals("")) {
// Set the link URL to the new short URL
short_link_url.setText(shortURL);
} else {
CommonFuncs.showMessage(getApplicationContext(), getString(R.string.unable_to_shorten_link));
short_link_url.setHint(R.string.unable_to_shorten_link);
}
(请注意,CommonFuncs.showMessage() 是我自己对 toast 函数的封装,以便于调用)。
但是,Android Studio 随后会发出警告“AsyncTask 类应该是静态的,否则可能会发生泄漏”。
如果我将方法设为静态,则会收到一条警告,指出我想从 onPostExecute 调用的来自 MainActivity 的方法不能被调用,因为它是非静态的。
如果我将 MainActivity 中的那个方法设为静态方法,那么它就无法访问字符串资源和任何其他非静态方法——我就掉进了兔子洞!
如果我只是将代码从MainActivity 中的方法移动到onPostExecute 方法中,正如您所期望的那样,情况也是如此。
所以...
- 将 AsyncTask 作为非静态方法真的是一件坏事吗? (我的 应用程序似乎在 AS 中可以正常处理此警告,但我显然没有 想在我的应用中造成内存泄漏。
-
WeakReference方法实际上是更正确、更安全的方法吗? - 如果我使用
WeakReference方法,我如何创建像toasts这样需要在UI 线程上运行并访问字符串的东西 来自MainActivity的资源等?
我在某处读到了有关创建interface 的信息,但有点迷路了,再也找不到了。这也不会像WeakReference 那样对MainActivity 有同样的依赖,这是一件坏事吗?
我真的在寻找有关如何将一些数据返回到 MainActivity 和从 AsyncTask 的 UI 线程的最佳实践指南,该指南是安全的,不会有内存泄漏的风险。
【问题讨论】:
-
奇怪的故事。我在活动中有很多 AsyncTasks,但从未收到过这样的警告。请从任务中删除您自己的祝酒词,看看是否有什么不同。
-
删除 toast 没有任何区别。事实上,在我添加 toasts 之前很久我就遇到了这些问题。
标签: java android android-activity android-asynctask static-methods