如何将此 asyncTask 转换为 AsyncTaskLoader?

How to turn this asyncTask to AsyncTaskLoader?

由于 movieListFetcher.listType 是枚举,如何将这段 AsyncTask 代码转换为 AsyncTaskLoader?

class LoadMovieList extends AsyncTask<movieListFetcher.listType, Void, Void> {

    @Override
    protected Void doInBackground(movieListFetcher.listType... params) {
        movies = null;
        switch (params[0]) {
            case TOP_RATED:
                movies = new movieListFetcher().getTopRatedList();
                break;
            case MOST_POPULAR:
                movies = new movieListFetcher().getMostPopularList();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        if (movies != null) {
            adapter.notifyDataSetChanged();
            recyclerView.setAdapter(adapter);

        }
    }
}

使用 AsyncTaskLoader 的一般步骤:

o 第 1 步: 创建一个扩展 AsyncTaskLoader<D> 的自定义加载程序 class; D: 是从使用 loadInBackground() 方法实现的后台任务 return 返回的对象列表;然后覆盖以下方法:

  • loadInBackground() >> 在后台运行以加载繁重的工作.. 类似于 AsyncTask
  • doInBackground()
  • onStartLoading() >> 在加载程序创建后运行,就在 loadInBackground() 之前;可用于 return 使用 deliverResult() 以前加载的结果,或使用 forceLoad()
  • 通过 运行 后台任务再次加载新结果

o 第 2 步: 在需要后台进程的 Activity 中实施 LoaderCallbacks<D>。这需要实现3个方法:

  • onCreateLoader() >> 在主线程中运行以创建加载器实例
  • onLoadFinished() >> 在主线程中运行以提交后台结果并更新 UI .. 类似于 AsyncTask[=29 的 onPostExecute() =]

  • onLoaderReset() >> 重置加载程序数据

o 第 3 步: 在需要时使用 LoaderManager 在 activity:

中启动加载程序
  • 注意:(确保导入正确的 Loader 和 LoaderManager,以防您使用 V4 支持库)

要在您的示例中应用它:

第 1 步:

public class MovieLoader extends AsyncTaskLoader<List<Movie>> { // STEP 1

    private List<Movie> movies;
    private int mMovieType;

    MovieLoader(@NonNull Context context, Integer movieType) {
        super(context);
        mMovieType = movieType;
    }

    @Override
    public List<Movie> loadInBackground() {

        switch (mMovieType) {
            case TOP_RATED:
                movies = new movieListFetcher().getTopRatedList();
                break;
            case MOST_POPULAR:
                movies = new movieListFetcher().getMostPopularList();
        }

        return movies;
    }

    @Override
    protected void onStartLoading() {
        super.onStartLoading();
        if (movies != null) {
            // To skip loadInBackground() call
            deliverResult(movies);
        } else {
            // to run loadInBackground()
            forceLoad();
        }
    }
}

第 2 步和第 3 步:

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Movie>> { // STEP 2

    final int LOADER_ID = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // initialize RecyclerView Adapter
        // Set RecyclerView mAdapter
        mAdapter = new CustomAdapter(...);
        RecyclerView recyclerView = findViewById(...);
        recyclerView.setAdapter(mAdapter);

        // Loading data in background by instantiating a new loader
        getSupportLoaderManager().initLoader(LOADER_ID, null, this); // STEP 3
    }

    @NonNull
    @Override
    public Loader<List<Movie>> onCreateLoader(int id, Bundle args) {
        return new MovieLoader(MainActivity.this, TOP_RATED);
    }

    @Override
    public void onLoadFinished(@NonNull Loader<List<Movie>> loader, List<Movie> movies) {

        // Update UI
        if (movies != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onLoaderReset(@NonNull Loader<List<Movie>> loader) {
        mAdapter.setMovies(new ArrayList<Movie>()); // create this custom method in your recyclerView adapter
    }

}

请注意,Loader 现已弃用,取而代之的是 LiveData & ViewModels

希望这能满足您的需求,您可以查看此tutorial了解更多信息