活动空指针异常 - 如何调试

时间:2016-12-15 11:05:07

标签: android android-activity nullpointerexception reference

我有一个“SignUpActivity”用户可以登录我的应用程序,在极少数情况下(我只有少数来自Fabric,Crashlytics),在显示对话框之前,此特定活动正在完成。为了澄清这一点,请检查以下代码:

  private void register() {
    final ProgressDialog dialog = new ProgressDialog(this);
    dialog.setTitle("Registering");
    dialog.setMessage("Please wait..");
    if (dialogReady(dialog)) {
        dialog.show();
    }
    final AlertDialog alert = new AlertDialog.Builder(this)
            .setTitle("Error Occured")
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                }
            }).create();


    new ApiService(this).signUp(signUpModel).enqueue(new Callback<Void>() {
        @Override
        public void onResponse(Call<Void> call, Response<Void> response) {
            if (response.isSuccessful()) {
                //code
                finish();
            } else {
                if (dialogReady(dialog) && dialogReady(alert)) {
                    dialog.dismiss();
                    alert.setMessage(response.message());
                    alert.setMessage("Email already exists");
                    alert.show();
                }
            }
        }

        @Override
        public void onFailure(Call<Void> call, Throwable t) {
            if (dialogReady(dialog) && dialogReady(alert)) {
                dialog.dismiss();
                alert.setMessage("Check your internet connection");
                alert.show();
            }
        }
    });
}

我如何设法重新创建问题是在Developer选项中设置“Do not keep activities”。我设法通过使用我创建的dialogReady方法解决了这个问题:

 private boolean dialogReady(Dialog dialog) {
    return (dialog != null && !this.isFinishing());
}

然而,我真的很想知道为什么我的活动从代码中清楚地完成了,在显示或解除对话之前没有办法(或者有)完成它。我检查了Crashlytics并且所有设备都有30 +%的RAM可用,活动本身非常简单,无论如何都不会使用太多的内存。

引用活动时也会弹出。我有一个活动,我们称它为A. A打开一个活动B,它使用A中的静态变量,称之为A.listener。当它在活动B中将它分配给该侦听器的新实例时,它会在A上抛出空指针异常。我无法通过“不要保留活动”重新创建它,这只会在少数设备上发生。

我怎么能想到一种重现问题的方法。我可以遵循一个很好的过程来调试这个罕见的问题。

谢谢。

编辑:我正在做的电话(新的ApiService ....)是异步请求 *(使用改装)

2 个答案:

答案 0 :(得分:0)

当您想要显示对话框时,首先检查活动!= null和!activity.isfinishing()如:

if(!isFinishing())
{
    //show alert
}

答案 1 :(得分:0)

@PampaZiya,我认为你必须使用Weak Reference活动

活动的上下文存储在Weak Reference中,它将在弹出初始化中使用,因此在活动完成后活动的引用仍然存在,然后通过使用此引用,不会发生崩溃。

你可以使用弱活动参考

WeakReference<Activity> weakReferenceActivity;

将onCreate of activity初始化为

weakReferenceActivity = new WeakReference<Activity>(activity);

现在,使用此引用初始化进度条或progressdialog,您甚至可以在AlertDialog中使用它。

final ProgressDialog dialog = new ProgressDialog(weakReferenceActivity );

final AlertDialog alert = new AlertDialog.Builder(weakReferenceActivity );

现在,只要您的活动完成对话,请使用以下引用解除,以便崩溃不会出现在图片中。