WeakReference/AsyncTask pattern in android(android 中的 WeakReference/AsyncTask 模式)
问题描述
我有一个关于 android 中这种简单频繁发生的情况的问题.
I have a question regarding this simple frequently occurring situation in android .
我们有一个 main Activity,我们调用了一个 AsyncTask 以及 mainActivity 的引用,以便 AsyncTask 可以更新 MainActivity 上的视图.
We have a main activity , we invoke an AsyncTask alongwith the reference of the mainactivity , so that that the AsyncTask can update the views on the MainActivity.
我将把事件分解成几个步骤
I will break down the event into steps
- MainActivity 创建一个 AyncTask ,将其引用传递给它.
- AysncTask ,开始工作,例如下载十个文件
- 用户更改了设备的方向.这会导致 AsyncTask 中的孤儿指针
- 当 AsyncTask 完成并尝试访问活动以更新状态时,由于空指针而崩溃.
上面的解决方法是按照《Pro Android 4》一书的建议,在AsyncTask中保留一个WeakReference
The solution for the above is to keep a WeakReference in the AsyncTask as recommended by the book "Pro Android 4"
WeakReference<Activity> weakActivity;
in method onPostExecute
Activity activity = weakActivity.get();
if (activity != null) {
// do your stuff with activity here
}
这是如何解决这种情况的?
How does this resolve the situation ?
我的问题是,如果我的 asynctask 正在下载 10 个文件,并且在 5 个文件完成后重新启动该活动(由于方向更改),那么我的 FileDownloadingTask 是否会再次被调用?
My question it , if my asynctask is downloading ten files , and upon completion of 5 the activity is restarted (because of an orientation change) then would my FileDownloadingTask be invoked once again ?.
最初调用的前一个 AsyncTask 会发生什么?
What would happen to the previous AsyncTask that was initially invoked ?
谢谢,对于问题的长度,我深表歉意.
Thank you , and I apologize for the length of the question .
推荐答案
这是如何解决这种情况的?
How does this resolve the situation ?
WeakReference
允许对 Activity
进行垃圾收集,因此您不会有内存泄漏.
The WeakReference
allows the Activity
to be garbage collected, so you don't have a memory leak.
空引用意味着 AsyncTask
不能 盲目尝试更新不再附加的用户界面,这会引发异常(例如视图未附加到窗口经理).当然,您必须检查 null 以避免 NPE.
A null reference means that the AsyncTask
cannot blindly try to update a user-interface that is no longer attached, which would throw exceptions (e.g. view not attached to window manager). Of course you have to check for null to avoid NPE.
如果我的 asynctask 正在下载 10 个文件,并且在 5 个文件完成后重新启动 Activity(由于方向更改),那么我的 FileDownloadingTask 会再次被调用吗?.
if my asynctask is downloading ten files , and upon completion of 5 the activity is restarted (because of an orientation change) then would my FileDownloadingTask be invoked once again ?.
取决于您的实现,但可能是的 - 如果您不刻意做一些事情来使重复下载变得不必要,例如将结果缓存在某处.
Depends on your implementation, but probably yes - if you don't deliberately do something to make a repeat download unnecessary, such as caching the results somewhere.
最初调用的前一个 AsyncTask
会发生什么?
What would happen to the previous
AsyncTask
that was initially invoked ?
在早期版本的 Android 中,它会一直运行到完成,下载所有文件只是为了将它们扔掉(或者可能缓存它们,具体取决于您的实现).
In earlier versions of Android it would run to completion, downloading all of the files only to throw them away (or perhaps cache them, depending on your implementation).
在较新的 Android 中,我怀疑 AsyncTask
与启动它们的 Activity
一起被杀死,但我怀疑的依据只是内存泄漏RoboSpice(见下文)的演示实际上并没有泄漏到我的 JellyBean 设备上.
In newer Android's I am suspicious that AsyncTask
's are being killed along with the Activity
that started them, but my basis for suspicion is only that the memory-leak demo's for RoboSpice (see below) do not actually leak on my JellyBean devices.
如果我可以提供一些建议:AsyncTask
不适合执行潜在的长时间运行的任务,例如网络.
If I may offer some advice: AsyncTask
is not suitable for performing potentially long running tasks such as networking.
IntentService
是一种更好(而且仍然相对简单)的方法,前提是您可以接受单个工作线程.如果您想控制线程池,请使用(本地)Service
- 并注意不要在主线程上工作!
IntentService
is a better (and still relatively simple) approach, if a single worker thread is acceptable to you. Use a (local) Service
if you want control over the thread-pool - and be careful not to do work on the main thread!
RoboSpice 如果您正在寻找一种在后台可靠地执行网络的方法,那么它看起来不错(免责声明:我没有尝试过;我没有附属).有一个 RoboSpice Motivations 演示应用在 Play 商店中,它解释了为什么您应该通过演示 AsyncTask
可能出错的所有事情来使用它 - 包括 WeakReference 解决方法.
RoboSpice seems good if you are looking for a way to reliably perform networking in the background (disclaimer: I have not tried it; I am not affiliated). There is a RoboSpice Motivations demo app in the play store which explains why you should use it by demo-ing all the things that can go wrong with AsyncTask
- including the WeakReference workaround.
另见此线程:是 AsyncTask真的概念上有缺陷还是我只是遗漏了什么?
更新:
我创建了一个 github 项目,其中包含使用 下载的示例IntentService
用于另一个 SO 问题(How to fix android.os.NetworkOnMainThreadException?),但是我认为这在这里也很重要.它还有一个额外的好处,即通过 onActivityResult
返回结果,当您旋转设备时正在运行的下载将传送到重新启动的 Activity
.
I created a github project with an example of downloading using IntentService
for another SO question (How to fix android.os.NetworkOnMainThreadException?), but it is also relevant here, I think. It has the added advantage that, by returning the result via onActivityResult
, a download that is in flight when you rotate the device will deliver to the restarted Activity
.
这篇关于android 中的 WeakReference/AsyncTask 模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:android 中的 WeakReference/AsyncTask 模式
基础教程推荐
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- Java:带有char数组的println给出乱码 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- 降序排序:Java Map 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01