我的活动正在尝试创建一个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


当前回答

伙计们,我有个小抄。 创建一个文件,给它任何名字,然后在它写这段代码

fun Context.alertdialog(context: Context, msg: String, icon: Drawable, title:String){
    val alertDialog = AlertDialog.Builder(context)
    alertDialog.setIcon(icon)
        .setTitle(title)
        .setMessage(msg)
    alertDialog.show()
}

现在,当你需要显示一个警告对话框时,只需要在任何地方使用这个方法

requireActivity().alertdialog(requireContext(), resources.getString(R.string.pass_title),
                resources.getDrawable(R.drawable.pass_ic_name), "title")

古德勒克 在芬兰湾的科特林

其他回答

或者另一种可能是创建Dialog,如下所示:

final Dialog dialog = new Dialog(new ContextThemeWrapper(
            this, R.style.MyThemeDialog));

小技巧:你可以防止GC破坏你的活动(你不应该这样做,但它可以在某些情况下有所帮助。当不再需要时,不要忘记将contextForDialog设置为null):

public class PostActivity extends Activity  {
    ...
    private Context contextForDialog = null;
    ...
    public void onCreate(Bundle savedInstanceState) {
        ...
        contextForDialog = this;
    }
    ...
    private void showAnimatedDialog() {
        mSpinner = new Dialog(contextForDialog);
        mSpinner.setContentView(new MySpinner(contextForDialog));
        mSpinner.show();
    }
    ...
}

*****版本*****

您应该传递this@YourActivity而不是applicationContext或baseContext

尝试getParent()在上下文的参数位置,如new AlertDialog.Builder(getParent());希望它能起作用,它对我很有效。

在Activity中使用:

MyActivity.this

在片段:

getActivity();