如何防止JobService使用的AsyncTask中的Context泄漏

时间:2017-08-30 15:22:08

标签: android android-asynctask firebase-job-dispatcher

我需要做一些背景工作,需要在JobService中使用Context(我使用Firebase JobDispatcher,因为我们支持api 16+)我已经阅读了很多关于JobService和AsyncTasks的文章但是如果你需要一个上下文,我无法找到关于如何组合它们的任何好文章。

我的JobService

import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;

public class AsyncJobService extends JobService {

    @Override
    public boolean onStartJob(JobParameters job) {
        new AsyncWork(this, job).execute();
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters job) {
        return false;
    }
}

我的AsyncTask

import android.os.AsyncTask;
import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;

class AsyncWork extends AsyncTask<Void, Void, Void> {

    private JobService jobService;

    private JobParameters job;

    AsyncWork(JobService jobService, JobParameters job) {
        this.jobService = jobService;
        this.job = job;
    }

    @Override
    protected Void doInBackground(Void... voids) {
        // some work that needs context
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // some work that needs context
        jobService.jobFinished(job, false);
    }
}

这会发出警告,指出AsyncWork类中的jobService属性正在泄漏上下文对象。我理解为什么会传递一个Activity或Fragment,但这是一个应该存在的JobService,直到我调用jobFinished()。我做错了什么还是可以忽略警告?

2 个答案:

答案 0 :(得分:1)

你不能忽视警告。由于Context保留对Context的引用,因此在任务完成之前无法对Context进行GC:onPause内存泄漏。有两种解决方案:

  1. 使用长期存在的上下文,无论如何,应用程序上下文。
  2. 将异步任务的生命周期与其拥有引用的上下文的生命联系起来:在{{1}}中取消它

答案 1 :(得分:0)

要处理泄漏,您需要对JobService对象使用WeakRefernce类

class AsyncWork extends AsyncTask<Void, Void, Void> {

  private WeakReference<JobService> jobServiceWeakReference;
  private JobParameters job;

  AsyncWork(JobService jobService, JobParameters job) {
      this.jobServiceWeakReference = new WeakReference<>(jobService);
      this.job = job;
  }

  @Override
  protected Void doInBackground(Void... voids) {
      // some work that needs context
        return null;
    }

  @Override
  protected void onPostExecute(Void aVoid) {
      super.onPostExecute(aVoid);
      // some work that needs context
      jobServiceWeakReference.get().jobFinished(job, false);
  }
}