Android Fragment调用外部类showAlert方法报空指针的解决方案
首先咱们来搞清楚为什么会出现这个崩溃:你直接用new AddImages()创建了一个AddImages的实例,但这个实例并没有被添加到Fragment的生命周期中——也就是说它的getContext()会返回null,而AlertDialog.Builder初始化时需要一个有效的Context,这就导致了NullPointerException。
下面给你几个可行的解决方案,按推荐程度排序:
方案1:将showAlert改为静态方法并传入Context
把AddImages中的showAlert方法改成静态的,并且让调用者传入Context,这样就不需要依赖AddImages的实例了:
修改AddImages.java中的showAlert方法:
// 修改为静态方法,接收Context参数 public static void showAlert(Context context, String title, String message) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setMessage(message); builder.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.show(); }
然后在AddCategory的点击事件中这样调用:
// 用Fragment的getContext()传入有效的上下文 AddImages.showAlert(getContext(), "Error", "Please fill all the details");
方案2:封装成通用的弹窗工具类
如果你的项目中多处需要弹出这类提示,更推荐把弹窗逻辑抽成一个独立的工具类,这样代码更解耦,复用性也更高:
创建一个DialogUtils.java类:
import android.content.Context; import android.support.v7.app.AlertDialog; import android.content.DialogInterface; public class DialogUtils { // 通用的提示弹窗方法 public static void showAlert(Context context, String title, String message) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setMessage(message); builder.setNeutralButton("Dismiss", (dialog, which) -> dialog.dismiss()); builder.show(); } }
然后不管是AddCategory还是AddImages,都可以直接调用这个工具类:
DialogUtils.showAlert(getContext(), "Error", "Please fill all the details");
方案3:获取已挂载的AddImages实例(不推荐)
如果AddImages是已经添加到当前Activity中的Fragment,你可以通过FragmentManager去获取它的实例,但这种方式耦合度很高,而且如果AddImages没被加载的话还是会出问题,所以只在特殊场景下使用:
// 在AddCategory中获取已存在的AddImages实例 AddImages addImagesFragment = (AddImages) getActivity().getSupportFragmentManager().findFragmentByTag("AddImagesTag"); if (addImagesFragment != null) { addImagesFragment.showAlert("Error", "Please fill all the details"); }
注意这里需要给AddImages添加Tag,在添加Fragment时指定:getSupportFragmentManager().beginTransaction().add(R.id.container, new AddImages(), "AddImagesTag").commit();
总结一下,推荐用方案1或方案2,它们的代码耦合度低,逻辑更清晰,也能彻底解决你遇到的NullPointerException问题。
内容的提问来源于stack exchange,提问作者user8281559

