I have the following fragment which loads a lot of data , this fragment has an inner static class which extends AsyncTask in the following way with weak reference to the fragment itself to prevent memory leaks:
public class PokemonDescriptionFragment extends Fragment {
////////Code
private static class LoadPokemonData extends AsyncTask<Void, Void, Pokemon> {
private WeakReference<PokemonDescriptionFragment> appReference;//FIXME Should I pass fragment as weak reference?
LoadPokemonData(PokemonDescriptionFragment context) {
appReference = new WeakReference<>(context);
}
/**
* Executed before starting the BACKGROUND THREAD
* Executed in the MAIN THREAD
*/
@Override
protected void onPreExecute() {
final PokemonDescriptionFragment fragment = appReference.get();
if (fragment == null) return;
GenericUtils.changeVisibility(View.VISIBLE, fragment.pokedexDataProgressBar, fragment.biologyProgressBar, fragment.statsDataProgressBar, fragment.abilitiesProgressBar, fragment.etymologyProgressBar);
GenericUtils.changeVisibility(View.GONE, fragment.llPokedexContainer);
}
/**
* Executes after onPreExecute.
* Is executed in the BACKGROUND THREAD
* Here you can call "publishProgress" method that executes the "onProgressUpdate" method in Main thread ,
* however , in this case , as I use indeterminated progress bar isn't necessary
*
* @return its sends the values to "onPostExecute"
*/
@Override
protected Pokemon doInBackground(Void... params) {
final PokemonDescriptionFragment fragment = appReference.get();
if (fragment == null) return null;
fragment.initializePokemonData();
return fragment.selectedPokemon;
}
/**
* Executes after doInBackground
* Executed in the MAIN THREAD
*/
@Override
protected void onPostExecute(Pokemon pokemon) {
final PokemonDescriptionFragment fragment = appReference.get();
if (fragment == null) return;
if (Objects.nonNull(pokemon)) {
MainActivity.setSelectedPokemon(pokemon);
fragment.abilityAdapter.refreshAbilities(fragment.abilityList);
}
GenericUtils.changeVisibility(View.GONE, fragment.pokedexDataProgressBar, fragment.biologyProgressBar, fragment.statsDataProgressBar, fragment.abilitiesProgressBar, fragment.etymologyProgressBar);
GenericUtils.changeVisibility(View.VISIBLE, fragment.llPokedexContainer);
fragment.displayFullData();
}
}
However , im not sure if this is 100% safe , I pass the fragment as weak reference because I need to access to some methods and attributes that the fragment has .Also , if you check my code I declare 3 times :
final PokemonDescriptionFragment fragment = appReference.get();
if (fragment == null) return null;
In the async task instead of declaring it as a global attribute of async task and referencing it in the 3 methods , is this correct ? Is there any problem if I add it as a global attribute of Asny task?