I am quite new to the Android Development and I really need your help. My problem is in the MainActivity
below. The app essentially displays a list of movies in the main activity and the movie details in another activity. And the problem is that whenever a user comes back from the MovieActivity
to the MainActivity
, the loader starts loading data again, although the movies are already there. And then it can not stop loading the data. It is really annoying. I want to get rid of this. So when a user comes back to the MainActivity, the loader will know that there is already loaded data and will not load anything again.If it helps, here is my full GitHub repo https://github.com/mateuszwojnarowicz/PopularMovies
I am stuck for about 3 weeks and have tried hundreds of possible solutions. Nothing seems to work. I feel really desperate.
Thank you so much for help,
Matthew
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<String> {
private MovieAdapter mAdapter;
private ArrayList<Movie> mMoviesCollection;
private SharedPreferences sharedPreferences;
private Resources resources;
private LoaderManager loaderManager;
private Loader<String> loader;
private RecyclerView.LayoutManager layoutManager;
private String sortBy;
@BindView(R.id.pb)
ProgressBar progressBar;
@BindView(R.id.er)
TextView errorTextView;
@BindView(R.id.rv)
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mMoviesCollection = new ArrayList<Movie>();
sharedPreferences = getSharedPreferences(Constants.SHARED_PREFS, Activity.MODE_PRIVATE);
resources = getResources();
sortBy = sharedPreferences.getString(Constants.KEY_SORT, null);
setSharedPref();
layoutManager = new GridLayoutManager(this, calculateNoOfColumns(this));
loaderManager = getLoaderManager();
loader = loaderManager.getLoader(Constants.LOADER_MOVIES_ID);
initialize();
makeOperationLoadMovies(sortBy);
}
public static int calculateNoOfColumns(Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
int noOfColumns = (int) (dpWidth / 150);
return noOfColumns;
}
//Set first-launch pref and set title according to pref
private void setSharedPref(){
if(!sharedPreferences.contains(Constants.KEY_SORT)) {
saveData(Constants.VALUE_POP);
setTitle(resources.getString(R.string.title_pop));
} else {
if (Objects.equals(sharedPreferences.getString(Constants.KEY_SORT, null), Constants.VALUE_POP)) {
setTitle(resources.getString(R.string.title_pop));
}
if (Objects.equals(sharedPreferences.getString(Constants.KEY_SORT, null), Constants.VALUE_TOP)) {
setTitle(resources.getString(R.string.title_top));
}
}
}
//Set up the RecyclerView
private void initialize(){
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
mMoviesCollection = new ArrayList<>();
mAdapter = new MovieAdapter(mMoviesCollection, this, this);
recyclerView.setAdapter(mAdapter);
}
private void makeOperationLoadMovies(String SORT_BY){
Bundle bundle = new Bundle();
bundle.putString(Constants.LOADER_MOVIES_EXTRA, SORT_BY);
if(recyclerView.isDirty()){
}
else if(loader==null){
loaderManager.initLoader(Constants.LOADER_MOVIES_ID, bundle, this);
}else{
loaderManager.restartLoader(Constants.LOADER_MOVIES_ID, bundle, this);
}
}
//Update shared pref
private void saveData(String SORT_VALUE){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(Constants.KEY_SORT, SORT_VALUE);
editor.apply();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.menu_fav:
startActivity(new Intent(MainActivity.this, FavoritesActivity.class));
break;
case R.id.menu_pop:
saveData(Constants.VALUE_POP);
Toast.makeText(this, resources.getString(R.string.message_popularity),Toast.LENGTH_LONG).show();
break;
case R.id.menu_top:
saveData(Constants.VALUE_TOP);
Toast.makeText(this, resources.getString(R.string.message_rating),Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPause() {
super.onPause();
Parcelable recyclerViewState;
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();//save
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
@Override
protected void onPostResume() {
super.onPostResume();
Parcelable recyclerViewState;
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();//save
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
@SuppressLint("StaticFieldLeak")
@Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
return new AsyncTaskLoader<String>(this) {
@Override
protected void onStartLoading() {
super.onStartLoading();
forceLoad();
progressBar.setVisibility(View.VISIBLE);
errorTextView.setVisibility(View.INVISIBLE);
}
@Override
public void deliverResult(String data) {
super.deliverResult(data);
}
@Override
public String loadInBackground() {
String jsonString = "";
URL url = NetworkUtils.buildUrl(args.getString(Constants.LOADER_MOVIES_EXTRA));
try {
jsonString += NetworkUtils.getResponseFromHttpUrl(url);
} catch (IOException e) {
e.printStackTrace();
}
if(jsonString.isEmpty()){
} else {
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(Constants.JSON_KEY_MOVIE_RESULTS);
for (int i = 0; i < jsonArray.length(); i++) {
//Get 1 movie from JSON
String mTitle;
int mId;
String mPosterUrl;
String mPlot;
double mUserRating;
String mReleaseDate;
JSONObject Jmovie = (JSONObject) jsonArray.get(i);
mTitle = Jmovie.getString(Constants.JSON_KEY_MOVIE_TITLE);
mId = Jmovie.getInt(Constants.JSON_KEY_MOVIE_ID);
mPosterUrl = NetworkUtils.getPosterString(Jmovie.getString(Constants.JSON_KEY_MOVIE_POSTER_PATH));
mPlot = Jmovie.getString(Constants.JSON_KEY_MOVIE_OVERVIEW);
mUserRating = Jmovie.getDouble(Constants.JSON_KEY_MOVIE_VOTE_AVERAGE);
mReleaseDate = Jmovie.getString(Constants.JSON_KEY_MOVIE_RELEASE_DATE);
//Get videos
ArrayList<Video> mVideos = new ArrayList<Video>();
URL videosURL = NetworkUtils.buildUrlVideos(String.valueOf(mId));
String videosJSON = NetworkUtils.getResponseFromHttpUrl(videosURL);
JSONObject jsonObjectVideos = new JSONObject(videosJSON);
JSONArray jsonArrayVideos = jsonObjectVideos.getJSONArray(Constants.JSON_KEY_VIDEO_RESULTS);
if(jsonArrayVideos.length()==0){
mVideos = null;
} else {
for(int v = 0; v < jsonArrayVideos.length(); v++){
JSONObject Jvideo = (JSONObject) jsonArrayVideos.get(v);
String mVideoName;
String mVideoUrlString;
mVideoName = Jvideo.getString(Constants.JSON_KEY_VIDEO_NAME);
mVideoUrlString = "https://www.youtube.com/watch?v="+Jvideo.getString(Constants.JSON_KEY_VIDEO_KEY);
Video video = new Video(mVideoName, mVideoUrlString);
mVideos.add(video);
}
}
//GetReviews
ArrayList<Review> mReviews = new ArrayList<Review>();
URL reviewsURL = NetworkUtils.buildUrlReviews(String.valueOf(mId));
String reviewsJSON = NetworkUtils.getResponseFromHttpUrl(reviewsURL);
JSONObject jsonObjectReviews = new JSONObject(reviewsJSON);
JSONArray jsonArrayReviews = jsonObjectReviews.getJSONArray(Constants.JSON_KEY_REVIEW_RESULTS);
if(jsonArrayReviews.length()!=0) {
for(int r = 0; r < jsonArrayReviews.length(); r++){
JSONObject Jreview = (JSONObject) jsonArrayReviews.get(r);
String mReviewName;
String mReviewText;
mReviewName = Jreview.getString(Constants.JSON_KEY_REVIEW_AUTHOR);
mReviewText = Jreview.getString(Constants.JSON_KEY_REVIEW_CONTENT);
Review review = new Review(mReviewName, mReviewText);
mReviews.add(review);
}
}
Movie movie = new Movie(mTitle, mId, mPosterUrl, mPlot, mUserRating, mReleaseDate, mVideos, mReviews);
mMoviesCollection.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
return null;
}
};
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
progressBar.setVisibility(View.GONE);
mAdapter.notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<String> loader) {
}
}