JobSchedule 和静态匿名 AsyncTask

JobSchedule and static anonymous AsyncTask

我正在学习如何将 Android 中的 JobScheduleAsyncTasks 结合使用。按照一些指南,我有以下 JobService 实现:

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class TaskJobService extends JobService {

    private WaitTask mWaitTask = null;

    @Override
    public boolean onStartJob(final JobParameters params) {
        mWaitTask = new WaitTask(){
            @Override
            protected void onPostExecute(Boolean result){
                super.onPostExecute(result);
                jobFinished(params, !result);
            }
        };
        mWaitTask.execute();
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        if (mWaitTask != null){
            mWaitTask.cancel(true);
        }
        return true;
    }
}

在我的 MainActivity:

public class MainActivity extends AppCompatActivity {
    int JOB_ID = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        WaitTask waitTask = new WaitTask();
//        waitTask.execute();
        ComponentName componentName = new ComponentName(this, TaskJobService.class);
        JobScheduler jobScheduler = (JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE);
        jobScheduler.schedule(new JobInfo.Builder(JOB_ID,componentName).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).build());
    }

    public void startMain2(View v){
        Intent intent = new Intent(this, Main2Activity.class);
        startActivity(intent);
    }
}

我在 JobService-class 中收到可能发生泄漏的警告:

This AsyncTask class should be static or leaks might occur 
A static field will leak contexts.  Non-static inner classes have an implicit reference to their outer class. If that outer class is for example a Fragment or Activity, then this reference means that the long-running handler/loader/task will hold a reference to the activity which prevents it from getting garbage collected.  Similarly, direct field references to activities and fragments from these longer running instances can cause leaks.  ViewModel classes should never point to Views or non-application Contexts.

问题是我想 Task 继续,即使我去 MainActivity2

像我一样打jobFinished就够了吗?还是更需要避免内存泄漏?

当您创建一个非静态内部 class 时,它包含对包含 class 的引用。在您的情况下,WaitTask 是内部匿名 class,它可能比您的 TaskJobService 寿命更长,因为 WaitTask 隐式引用了您的服务 class。这将防止您的 TaskJobService 被垃圾收集,从而导致内存泄漏。

解决方案是创建静态嵌套 class 或直接使用顶级 class。