问题描述
我在应用程序中使用片段.我创建了一个称为BaseFragment的父类,所有其他片段都对该Basefrgment进行了扩展,下面是该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()+"); }
在使用活动作为上下文的所有其他片段中,我的问题是,以这种方式访问上下文是否不好,或者是否创建了内存泄漏.或者是否存在任何其他访问上下文的方法.是否提供了任何帮助.
我认为您存储context
的方式确实是最佳的,因为您可以在每个子片段实例中使用它.因为MainActivity
是片段中的一个实例变量,所以当片段被销毁时,它将被垃圾回收.而且,如果我对Activity-Fragment生命周期没有误解,那么当您的活动轮换时,将创建新的片段,而较旧的片段实例将被销毁.所以,我们在那里也很好.但是,您需要小心上下文变量声明:public MainActivity activity;
这使得它可以从任何地方访问.任何类都可以调用context = fragIns.activity
之类的内容并将其保存在其中.这对您来说真的很糟糕,因为现在它拥有对该上下文变量的引用.现在,当不再需要您的片段时,就不会再对其进行垃圾回收了,因为其他某个类持有对该变量之一的引用.您会发现自己在内存泄漏之乡".
请确保您持有该变量的金额很高,并且它的引用没有传递给其他类.由于它是超类,因此您可以将其定义为:
protected MainActivity activity;
这应该可以完成工作.
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.
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.
这篇关于在片段中使用上下文的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!