调用另一个片段的方法时发生 ClassCastException

ClassCastException occurs when calling another fragment's method

**重新附上相关代码


当我 运行 FragmentB 中的电子邮件应用程序时,activity 的 'onStop' 被调用。
此时FragmentA在'onStop'中的方法不起作用

※ FragmentA 和 FragmentB 具有相同的父级 Activity
※ 应用在FragmentB中终止不会报错。

MainActivity.java

   public class MainActivity extends FragmentActivity {
    
    public Fragment fragmentA, fragmentB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (findViewById(R.id.fragment_container) != null) {
            if (savedInstanceState != null) {
                return;
            }
            fragmentA = new FragmentA();
            fragmentB = new FragmentB();
           
            fragmentA.setArguments(getIntent().getExtras());
           
            getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, fragmentA).commit();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
      
        ((FragmentA) getSupportFragmentManager().findFragmentById(R.id.fragment_container)).saveData();

    }

}

FragmentA.java

    View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_timer, container, false);
    if(isLoadData){ loadData(); }
    return view;
}

public void saveData() {
    SharedPreferences timerSharedPref = getActivity().getSharedPreferences("timer", Context.MODE_PRIVATE);
    
    //...
    
    SharedPreferences.Editor editor = timerSharedPref.edit();
    String json = jsonArray.toString();
    editor.putString("jsonString", json);
    editor.apply();
}

FragmentB.java

public class FragmentB extends Fragment implements View.OnClickListener {

View view;
CardView cvContactUs;
MainActivity activity;

@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    activity = (MainActivity) getActivity();
}
@Override
public void onDetach() {
    super.onDetach();
    activity = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.fragment_b, container, false);
    cvContactUs = view.findViewById(R.id.cv_contact_us);
    return view;
}
@Override
public void onStart() {
    super.onStart();
    cvContactUs.setOnClickListener(this);
}
@Override
public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.cv_contact_us) {
        sendEmail(getActivity(), "Ask a question", new String[]{"help_center@gmail.com"});
    }
}
public static void sendEmail(Context context, String title, String[] receivers){
    Intent email = new Intent(Intent.ACTION_SEND);
    email.putExtra(Intent.EXTRA_SUBJECT, title);
    email.putExtra(Intent.EXTRA_EMAIL, receivers);
    email.setType("message/rfc822");
    context.startActivity(email);
}

}

你说你收到了 ClassCastException。您发布的代码中唯一的 class 是

(FragmentA) getSupportFragmentManager().findFragmentById(...)

因此检查 findFragmentById 是否可能 return FragmentB 或其他。也许你想

  • 要么转换为共同的父级 activity
  • 在转换前检查 returned 值是否是 FragmentA 的实例

您在堆栈中有两个片段和一个 ID,并且 findFragmentByID() 方法 returns 将最后一个片段添加到容器中。很好,当应用程序以 FragmentA 结束时,我相信您没有任何错误,因为在 onStop() 方法中,您使用 FragmentA 进行转换,但如果您以FragmentB 在这种情况下,您正在通过 FragmentA 抛出 ClassCastException异常。所以我建议你使用findFragmentByTag()方法这里是一个例子

添加片段时:

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /*
         * rest of your code
         */
        // when you add the Fragment A
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment_container, new FragmentA(), "A")
                .commit();
        // when you add the Fragment A
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment_container, new FragmentB(), "B")
                .commit();
    }

当您调用 onStop() 方法时:

 @Override
    protected void onStop() {
        super.onStop();
        // ((FragmentA) getSupportFragmentManager().findFragmentByTag("A")).save();
        // ((FragmentB) getSupportFragmentManager().findFragmentByTag("B")).save();
        Fragment f = getSupportFragmentManager().findFragmentByTag("A");
        // you check if the fragment is add 
        if (f != null)
            ((FragmentA) f).save();
    }