在AsyncTask运行时销毁Activity时内存会发生什么?

时间:2014-10-25 20:27:27

标签: java android android-asynctask garbage-collection

我一直在玩我创建的应用程序。

  1. 活动A(第一个活动)有一个执行AsyncTask的按钮。此AsyncTask的doInBackground()对活动A中的选定值执行计算,其onPostExecute()启动活动B.

  2. 我点击按钮,然后在活动B开始之前我按回去销毁活动A.

  3. 应用程序关闭,然后重新启动活动B,并使用我的AsyncTask中的计算填充。

  4. this awesome blog解释了屏幕旋转时线程的内存泄漏,我在这里使用AsyncTask和后退按钮按下这些课程。不过,我还是有点困惑。

    1. 按回活动会破坏它。

    2. 我的asynctask正在一个被销毁的活动上运行,应该抛出一个NPE,因为它正在访问该活动中的列表元素。

    3. 但事实并非如此。什么被摧毁真的意味着呢?我认为这意味着Activity A引用及其视图层次结构将设置为null,以允许垃圾收集器在某个时间将其清除并回收内存。该博客称它没有,因此内存泄漏。

    4. 等等,活动A没有被破坏?但我看到它消失了......

      这是一个概念性问题,而不是目前为止的代码问题,但是根据要求:

      private class MyAsyncTask extends AsyncTask<ArrayList<Train>, Void, Void> {
      
          protected void onPreExecute() {
              // Runs on the UI thread before doInBackground
              spinWait.setVisibility(ProgressBar.VISIBLE);
              waitMsg.setText("Calculating Schedules....");
      
              spinWait.bringToFront();
              waitMsg.bringToFront();
          }
      
      
          @Override
          protected Void doInBackground(ArrayList<Train>... lolTrains) {
      
              try {
                  calcSchedules(lolTrains[0]);
              } catch (Exception e) {
                  Log.d("DEBUG", "Calculating schedules failed, " + e.getMessage());
              }
              return null;
          }
      
      
          @Override
          protected void onPostExecute(Void v) {
              // This method is executed in the UIThread
              spinWait.setVisibility(View.GONE);
              waitMsg.setVisibility(View.GONE);
      
              // if schedules is empty, show error dialog
              if (schedules.size() == 0) {
                  // show msg, etc
              } else {
                  Intent i = new Intent(getBaseContext(), ResultsActivity.class);
                  i.putExtra("results", schedules);
                  startActivity(i);
              }
          }
      }
      
      public void MethodInActivityA(View v) {
          new MyAsyncTask().execute(memberVarInActivityA);
      }
      

2 个答案:

答案 0 :(得分:1)

当你破坏你的活动时,你没有摧毁你的AsyncTask(基本上是Thread),试试这个

asyncTask.cancel(true);

onDestroy();方法

希望这会有所帮助

答案 1 :(得分:0)

在您的onPostExecute()上,当开始新活动时,请依次呼叫finsih()startActivity(i)。此finish()内部调用onDestroy。在这里,您需要手动清除Asynctask,因为Asynctask是Activity的内部类。甚至活动被破坏,这个内部类也拥有活动的引用。您需要通过asyncTask.cancel()手动清除引用。