دعاء مصطفى
دعاء مصطفى

Reputation: 45

How to turn this asyncTask to AsyncTaskLoader?

How to turn this code of AsyncTask to AsyncTaskLoader since movieListFetcher.listType is an enum?

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

        }
    }
}

Upvotes: 1

Views: 1329

Answers (1)

Zain
Zain

Reputation: 40830

General Steps for Using AsyncTaskLoader:

o Step 1: Create a custom Loader class which extends AsyncTaskLoader<D>; D: is the list of objects that are returned back from the background task which is implemented using loadInBackground() method; and then override below methods:

  • loadInBackground() >> runs in background to load the heavy work .. similar to doInBackground() of AsyncTask
  • onStartLoading() >> runs once the loader is created and just before loadInBackground(); can be used to return previous loaded results using deliverResult() or to load new results by running the background task again using forceLoad()

o Step 2: Implement LoaderCallbacks<D> in your Activity that requires the background process. This requires to implement 3 methods:

  • onCreateLoader() >> runs in main thread to create a loader instance
  • onLoadFinished() >> runs in main thread to submit background results & update UI .. similar to onPostExecute() of AsyncTask

  • onLoaderReset() >> reset loader data

o Step 3: use the LoaderManager to start your loader whenever you need that in your activity:

  • Note: (make sure to import the right Loader & LoaderManager in case you're using V4 support library)

To apply this in your example:

Step 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();
        }
    }
}

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

}

Please note that Loaders are now deprecated and replaced by LiveData & ViewModels

Hope this satisfies your need, and you can check this tutorial for more info

Upvotes: 2

Related Questions