Hardik Mehta Hardik Mehta - 4 months ago 15
Android Question

best way to use context in fragment

i m using fragments in my application. i created one Parent Class called BaseFragment and all other fragment extends this Basefrgment below is the snippet of this Basefragment

BaseFragment.java

public class BaseFragment extends Fragment {
public MainActivity activity;

@Override
public void onAttach(Context context) {
super.onAttach(context);
if (activity == null && context instanceof MainActivity) {
activity = (MainActivity) context;
}
}
}


public void replaceFragment(Fragment fragment, FragmentDetail last) {

fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
boolean push = true;
if (Validator.isNotNull(last)) {
push = false;
}
/*if(Validator.isNull(last)){
transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right);
}else{
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
}*/
transaction.add(R.id.frame_container, fragment, fragment.getClass().getName());
if (Validator.isNull(last) && preferences.getFragmentStack().size() > 0) {
last = preferences.getFragmentStack().lastElement();
}
if (Validator.isNotNull(last)) {
Fragment f = fragmentManager.findFragmentByTag(last.className);
if (Validator.isNotNull(f)) {
f.onPause();
transaction.remove(f);
}
}
last = new FragmentDetail(fragment.getClass().getName(), getTitle().toString(), preferences.isBack());
if (preferences.isBack() || preferences.getFragmentStack().size() == 0) {
if (push) {
preferences.getFragmentStack().push(last);
}
} else {
while (preferences.getFragmentStack().size() > 1) {
preferences.getFragmentStack().pop();
}
if (!preferences.getFragmentStack().lastElement().className.equals(last.className)) {
preferences.getFragmentStack().push(last);
}
}
transaction.commitAllowingStateLoss();
changeNavigationIcon();


// HWUtil.showToast(this, fragmentManager.getBackStackEntryCount() + "");
}

and in all other fragment i m using activity as a context,my question is whether it is bad way to access context in this way or whether it creates memory leak.or any other approach for accessing context..any help is appriciated.

Answer

I think the way you are storing the context is really optimal as with that you will be able to use it within each of your sub fragment instances. Because MainActivity is an instance variable in your fragment, it will be garbage collected when your fragment gets destroyed. And if I'm not mistaken about Activity-Fragment lifecycle, when your activity gets rotated, new fragments will be created and the older fragment instances will get destroyed. So, we're good there too. However, you need to be careful with your context variable declaration:

public MainActivity activity;

This makes it accessible from anywhere. Any class can call something like context = fragIns.activity and save it there. This will be really bad for you because now it holds a reference to that context variable. Now, when your fragment is no longer needed it will not be garbage collected because some other class is holding a reference to one of its variable. You'd find yourself in "memory leak town".

Make sure you hold this variable dearly and its reference is not passed to other classes. Since, its in a super class, you may define it as:

protected MainActivity activity;

This should do the job.