我的活动正在尝试创建一个AlertDialog,它需要一个上下文作为参数。如果我使用:

AlertDialog.Builder builder = new AlertDialog.Builder(this);

然而,我对使用“this”作为上下文持怀疑态度,因为即使在屏幕旋转这样简单的操作中,Activity被破坏和重新创建时,也有可能发生内存泄漏。来自Android开发者博客的相关文章:

There are two easy ways to avoid context-related memory leaks. The most obvious one is to avoid escaping the context outside of its own scope. The example above showed the case of a static reference but inner classes and their implicit reference to the outer class can be equally dangerous. The second solution is to use the Application context. This context will live as long as your application is alive and does not depend on the activities life cycle. If you plan on keeping long-lived objects that need a context, remember the application object. You can obtain it easily by calling Context.getApplicationContext() or Activity.getApplication().

但是对于AlertDialog(), getApplicationContext()或getApplication()都不能作为上下文,因为它会抛出异常:

"无法添加窗口-令牌null不是用于应用程序"

参考文献:1、2、3等。

所以,这真的应该被认为是一个“bug”,因为我们被正式建议使用Activity.getApplication(),但它并没有像宣传的那样发挥作用?

Jim


当前回答

使用MyDialog md = new MyDialog(MyActivity.this.getParent());

其他回答

我在一个片段中使用ProgressDialog,并在传递getActivity(). getapplicationcontext()作为构造函数参数时得到这个错误。将其更改为getActivity(). getbasecontext()也不起作用。

对我有效的解决方案是传递getActivity();即。

progressDialog = new progressDialog (getActivity());

如果你在活动之外,那么你需要在你的函数中使用“NameOfMyActivity”。this" as Activity Activity,示例:

public static void showDialog(Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setMessage("Your Message")
        .setPositiveButton("Yes", dialogClickListener)
        .setNegativeButton("No", dialogClickListener).show();
}


//Outside your Activity
showDialog(NameOfMyActivity.this);

如果你正在使用一个片段并使用AlertDialog/Toast消息,那么在context参数中使用getActivity()。

像这样

ProgressDialog pdialog;
pdialog = new ProgressDialog(getActivity());
pdialog.setCancelable(true);
pdialog.setMessage("Loading ....");
pdialog.show();

尝试使用对话框下面的活动上下文。但是当你使用“this”关键字时要小心,因为它不会每次都有效。

例如,如果你有两个选项卡TabActivity作为主机,每个选项卡是另一个活动,如果你试图从其中一个选项卡(活动)创建对话框,如果你使用"this",那么你会得到异常, 在这种情况下,对话框应该连接到主机活动,主机的一切和可见。(你可以说most visible parent Activity’s context)

我没有从任何文件中找到这个信息,但通过尝试。这是我的解决方案,没有强大的背景,如果有人有更好的知识,请随意评论。

你的对话框不应该是一个“需要上下文的长生命对象”。文档很混乱。基本上,如果你这样做:

static Dialog sDialog;

(注意静态)

然后在你参加的某个活动中

 sDialog = new Dialog(this);

您可能会在旋转或类似的过程中泄漏原始活动,从而破坏活动。(除非你在onDestroy中清理,但在这种情况下,你可能不会使Dialog对象静态)

对于某些数据结构,基于应用程序的上下文将它们设置为静态是有意义的,但对于与UI相关的东西,比如对话框,通常不是这样。就像这样:

Dialog mDialog;

...

mDialog = new Dialog(this);

很好,不应该泄漏活动,因为mDialog将与活动释放,因为它不是静态的。