Android AsynchTask在其调用Activity完成时正在工作

时间:2016-05-26 09:05:39

标签: android android-asynctask

我的活动已完成,而AsynchTask位于doinBackground()方法内。

当它达到postExecute()时,用于更新用户界面的活动已被销毁,但其TextView仍可在onPostExecute()中访问。
任何人都可以解释这是怎么回事吗?

5 个答案:

答案 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也可能导致内存泄漏(因为内部类保存对外部类的隐式引用)。