【问题标题】:Trying to open an Activity from an AlertDialog in a Fragment尝试从片段中的 AlertDialog 打开 Activity
【发布时间】:2026-02-02 07:45:01
【问题描述】:

所以,在对在片段内启动的 AlertDialog 进行一些确认后,我正在尝试打开一个新 Activity。

我的问题是上下文。我已经尝试过使用getActivity()getContext(),都无济于事。想法是通过此对话框确认用户操作(特别是删除帐户,因此将用户引导至特定活动很重要),并在确认后启动 IntroActivity。

这是我AlertDialog类的内容:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    final AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
    LayoutInflater inflater = getActivity().getLayoutInflater();
    final View view = inflater.inflate(R.layout.layout_excluir_usuario_dialog, null);

    dialog.setView(view)
            .setTitle("Deseja mesmo excluir a sua conta?")
            .setMessage("Excluir a sua conta resultará na eliminação completa dos seus dados do Salarium.")
            .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialogInterface, int i) {

                }
            })
            .setPositiveButton("Sim", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
                    FirebaseUser usuario = autenticacao.getCurrentUser();

                    usuario.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                Toast.makeText(dialog.getContext(), "E-mail de redefinição de senha enviado!", Toast.LENGTH_LONG).show();
                                Intent intent = new Intent(getActivity().getApplicationContext(), IntroActivity.class);
                                startActivity(intent);

                            } else {
                                Toast.makeText(dialog.getContext(), "Ocorreu um erro na exclusão da sua conta", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });

                }
            });
    return dialog.create();
}

无论我选择哪种上下文方法组合,最后我都会遇到 NullPointerExceptions。

    Process: com.filipewilliam.salarium, PID: 19838
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
        at com.filipewilliam.salarium.fragments.ExcluirUsuarioDialog$1$1.onComplete(ExcluirUsuarioDialog.java:55)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)```

【问题讨论】:

  • edit您的问题提供完整的stack trace
  • 完成了,对不起!
  • 尝试使用 onCreate 方法中的上下文。

标签: java android android-studio android-fragments android-alertdialog


【解决方案1】:

AlertDialog 在单击按钮时自动关闭对话框 - 即当您的 setPositiveButton OnClickListener 触发时。当对话框关闭时,DialogFragment 会自动删除。

因为您正在执行异步工作,所以您的结果返回在 Dialog 被关闭并且 DialogFragment 被删除后。此时,预计 DialogFragment 上的 dialog.getContext() 将为 null,而 getContext() 也将为 null。

没有办法将 AlertDialog 的行为更改为仅在异步回调完成后关闭,但您可以在启动异步工作之前保留 Context 并在异步调用完成时使用它:

@Override
public void onClick(DialogInterface dialogInterface, int i) {
  final Context context = getContext();
  autenticacao = ConfiguracaoFirebase.getFirebaseAutenticacao();
  FirebaseUser usuario = autenticacao.getCurrentUser();

  suario.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
      if (task.isSuccessful()) {
        Toast.makeText(context, "E-mail de redefinição de senha enviado!", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(context, IntroActivity.class);
        startActivity(intent);

      } else {
        Toast.makeText(context, "Ocorreu um erro na exclusão da sua conta", Toast.LENGTH_SHORT).show();
      }
    }
  });

请注意,这有一个缺点:如果您的 Activity 在异步工作运行时被销毁,您将继续保留对旧 Activity 的引用,而不是让它立即被垃圾回收。假设您的任务不会花费很长时间,这对您来说可能不是问题。

【讨论】:

  • 我已经尝试了您的解决方案,但它没有用,但我不知道问题是对话框被立即关闭。所以我所做的是新的方法来测试用户是否在调用对话框和活动的片段中登录/或存在。现在对话框可以工作了,您可以删除您的用户帐户,一旦您这样做了,您将进入 IntroActivity!非常感谢!
  • 您在运行代码时遇到了什么错误?如果是抱怨不是最终的,我已经在我的回答中添加了 final 到上下文中。
  • 是的@ianhanniballake,我已经用final 试过了。错误是 Fragment 未附加到 Activity。
【解决方案2】:

getActivity() 方法在您的函数中返回 null。您应该在初始化对话框时传递活动上下文。 你可以像答案here那样做

一旦你有了 Fight Context(Activity 继承自 Context),你就可以创建你的意图并从中启动 Activity

【讨论】:

    【解决方案3】:

    我认为这可能是问题所在 (Why does AlertDialog.Builder(Context context) only accepts Activity as a parameter?):

    getApplicationContext() 返回您的应用程序的上下文,这与您的活动上下文基本相同 - “大部分”是让您失望的原因。

    细节尚不清楚,但这是一个广泛遇到的问题,典型的答案是使用将警报写入屏幕的上下文。

    请注意,这不是 getApplicationContext() 返回的那个。

    【讨论】: