调用另一个片段的方法时发生 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();
}
**重新附上相关代码
当我 运行 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();
}