单击按钮后,我正在使用 EventBus 从一个 fragment 导航到另一个 fragment 。有时会出现以下错误且不可重现:
Fatal Exception: java.lang.IllegalStateException: Fragment already added: FragmentQuestion3_2{82d0763} (e57d5f9c-c80b-4f99-a4f4-e844bdabdef5) id=0x7f0a0487}
at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7211)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
这个问题有一些答案,但因为我使用的是 EventBus,所以对我没有任何帮助。这是显然已经添加的 fragment :
public class FragmentQuestion3_2 extends BaseFragment {
private ViewModelQuestionAnswer viewModel;
private String category;
private ImageView imageCategory;
private TextView question3;
PagerAdapter viewPagerAdapter;
public NonSwipeAbleViewPager optionAnswerViewPager;
private boolean isFragmentLoaded = false;
public FragmentQuestion3_2() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
EventBus.getDefault().register(this);
}
public static FragmentQuestion3_2 newInstance(String questionNumber) {
return new FragmentQuestion3_2();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init ViewModel
viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelQuestionAnswer.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_question, container, false);
imageCategory = view.findViewById(R.id.image_view_question);
question3 = view.findViewById(R.id.question);
optionAnswerViewPager = view.findViewById(R.id.option_answer_view_pager);
// Gets the category so the ImageView can be updated accordingly
viewModel.getCategory().observe(requireActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
category = s;
setUpCategoryImage();
}
});
// Gets the question
viewModel.getQuestion3().observe(requireActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
question3.setText(s);
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
if (!isFragmentLoaded) {
isFragmentLoaded = true;
init();
}
}
private void initOptionAnswerViewPager() {
viewPagerAdapter = new ViewPagerOptions3Round2(getChildFragmentManager(), 2);
Utils.getInstance().changePagerScroller(optionAnswerViewPager);
optionAnswerViewPager.setAdapter(viewPagerAdapter);
optionAnswerViewPager.setPagingEnabled(false);
optionAnswerViewPager.setOffscreenPageLimit(3);
}
@Override
protected void setupListeners() {
}
@Subscribe
public void setViewPagerPosition(SetViewPagerPosition setViewPagerPosition) {
optionAnswerViewPager.setCurrentItem(setViewPagerPosition.getPosition(), true);
}
@Override
public void init() {
initOptionAnswerViewPager();
}
@Override
public void onDetach() {
EventBus.getDefault().unregister(this);
super.onDetach();
}
}
我正在使用这个 FragmentStatePagerAdapter:public class QuestionsPagerAdapterRound2 extends FragmentStatePagerAdapter {
private static final String QUESTION_NUMBER = "question_number";
private int mNumOfTabs;
private final List<Fragment> mFragmentList = new ArrayList<>();
public QuestionsPagerAdapterRound2(FragmentManager fm, int NumOfTabs) {
super(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mNumOfTabs = NumOfTabs;
}
public void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentCategory_2.newInstance("1");
case 1:
return FragmentQuestion1_2.newInstance("2");
case 2:
return FragmentQuestion2_2.newInstance("3");
case 3:
return FragmentQuestion3_2.newInstance("4");
case 4:
return FragmentQuestionResult_2.newInstance("5");
default:
return null;
}
}
@Override
public int getCount() {
return mNumOfTabs;
}
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
}
在每个问题中,我都有第二个 ViewPager,因此 ViewPager 中有一个 ViewPager,这是第二个 ViewPager:public class ViewPagerOptions3Round2 extends FragmentStatePagerAdapter {
private int mNumOfTabs;
private final List<Fragment> mFragmentList = new ArrayList<>();
public ViewPagerOptions3Round2(FragmentManager fm, int NumOfTabs) {
super(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mNumOfTabs = NumOfTabs;
}
public void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentOptions3.newInstance();
case 1:
return FragmentAnswer3_2.newInstance();
default:
return null;
}
}
@Override
public int getCount() {
return mNumOfTabs;
}
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
}
这是我为打开下一个 fragment 而调用的类(class):public class SetQuestionAdapterPosition {
private Integer position;
public Integer getPosition() {
return position;
}
public void setPosition(Integer position) {
this.position = position;
}
public SetQuestionAdapterPosition(Integer position) {
this.position = position;
}
}
我正在使用这个电话 EventBus.getDefault().post(new SetQuestionAdapterPosition(1));
打开下一个 fragment 。我可以使用以下代码来防止应用程序崩溃吗? try {
EventBus.getDefault().post(new SetQuestionAdapterPosition(1));
} catch (Exception e){
Log.e("Answer2", e.toString());
}
有什么我可以在我的代码中添加的东西,所以在添加 fragment 之前它会检查它是否已经被添加以防止错误语句?我感谢每一个帮助和建议!
最佳答案
EventBus 经常会引入意大利面条式的代码,这种情况很可能是由于事件在非预期时间触发造成的。您没有在 EventBus.getDefault().post()
时发布整个逻辑。发生了,但我强烈建议仔细检查为什么它会触发同一个 fragment 两次。
然而,一个简单(但很麻烦)的修复方法是在使用 Fragment.isAdded() 添加之前检查 fragment 是否已经添加。 :
public void addFragment(Fragment fragment) {
if (!fragment.isAdded()) {
mFragmentList.add(fragment);
}
}
关于java - "Fragment already added"有时在将 EventBus 与 ViewPager 一起使用时发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63117607/