5

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

我的工作服务

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;
    }
}

我的异步任务

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()。我做错了什么还是可以忽略警告?

4

2 回答 2

1

您不能忽略警告。因为AsyncWork持有对 的引用,Context所以Context在任务完成之前无法对 GC 进行 GC:Context内存泄漏。有两种解决方案:

  1. 无论如何,使用长期存在的上下文,即应用程序上下文。
  2. 将异步任务的生命周期与它持有引用的上下文的生命周期联系起来:取消它onPause
于 2017-08-30T15:30:48.947 回答
0

要处理泄漏,您需要使用带有 JobService 对象的 WeakReference 类

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);
  }
}
于 2019-10-10T17:32:54.963 回答