我的活动已完成,而AsynchTask
位于doinBackground()
方法内。
当它达到postExecute()
时,用于更新用户界面的活动已被销毁,但其TextView
仍可在onPostExecute()
中访问。
任何人都可以解释这是怎么回事吗?
答案 0 :(得分:1)
在开始新活动之前,请致电取消AsyncTask
asynTask.cancel(true)
并在您的asynctasks doInBackground
方法中检查AsyncTask
是否被取消
@Override
protected String doInBackground(String... urls) {
for( !isCancelled()) {
//do some stuff
}
}
答案 1 :(得分:1)
Android活动具有特定的生命周期。当他们超过他们的Destroy生命周期状态时,他们不再可以被Android 使用,并且最终将被垃圾收集。
但是,当您将Activity引用或任何窗口小部件引用传递给AsyncTask时,这会阻止GC处理活动及其相关对象(例如视图和窗口小部件)。此外,AsyncTask在具有自己状态的单独线程中执行,将保存一个或多个无效的引用。由于您在AsyncTask中保留了引用,因此GC无法释放它们。
这就是为什么你必须非常小心使用带有Activity引用的AsyncTasks。另外,不要使用AsyncTasks来更新UI,还有其他方法可以做到这一点。
答案 2 :(得分:0)
这个问题希望能够解释它是如何发生的。 想想这个简单的java代码。
public class myClass{
public static void main(String[] args) {
int n=2;
MyThread t=new MyThread(n);
t.start();
n=4;
System.out.println("n from main "+n);
}
}
class MyThread extends Thread{
int n;
public MyThread(int n){
this.n=n;
}
@Override
public void run(){
try{
Thread.sleep(2000);
}catch(Throwable e){
System.out.println("error :"+e);
}
System.out.println("n from thread "+n);
}
}
输出将是,
n from main 4
n from thread 2
这是因为传递给线程的整数n的实例保存了它的值。这与您的AsyncTask中发生的情况相同。如果您创建一个静态变量并在新线程内对其进行引用,则会更改此行为。
答案 3 :(得分:0)
您的activity
可能因多种原因而被销毁,例如
activity
Activity
被杀死并重新创建Activity
您的逻辑需要在执行AsyncTask
时处理此类情况。在Activity
启动AsyncTask
后,它会在另一个线程中执行,并在结束后将结果发送回activity
。当后台activity
正在开展工作时,您的AsyncTask
可能会被杀死。一个好的做法是在cancel(boolean)
被杀(onDestroy)后调用activity
方法,如果你不想继续AsyncTask
的结果。
答案 4 :(得分:0)
AsyncTask(与标准java线程相同)不尊重主机Activity的生命周期。由开发人员实施适当的取消(如@mrDroid所示)。
您可以使用AsyncTaskLoader,因此您不必编写处理活动配置更改的代码。
请注意,即使没有直接引用主机Activity(如提到的@George Metaxas),非静态内部AsyncTask也可能导致内存泄漏(因为内部类保存对外部类的隐式引用)。