自定义Dialog.show()上的BadTokenException

时间:2015-04-16 12:49:18

标签: android dialog

我试图显示一个自定义对话框,并根据我在调用确认对话框.show()方法时传递的参数弹出此运行时错误。

错误日志是:

04-16 09:45:03.148: E/AndroidRuntime(13540): FATAL EXCEPTION: main
04-16 09:45:03.148: E/AndroidRuntime(13540): Process: com.moymer, PID: 13540
04-16 09:45:03.148: E/AndroidRuntime(13540): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.view.ViewRootImpl.setView(ViewRootImpl.java:554)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:259)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.app.Dialog.show(Dialog.java:286)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.moymer.fragments.AmigosFragmentNovo.showDialogDesfazerAmizade(AmigosFragmentNovo.java:2006)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.moymer.fragments.AmigosFragmentNovo$12.onItemLongClick(AmigosFragmentNovo.java:959)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.widget.AbsListView.performLongPress(AbsListView.java:2979)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:2928)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.os.Handler.handleCallback(Handler.java:733)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.os.Handler.dispatchMessage(Handler.java:95)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.os.Looper.loop(Looper.java:136)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.app.ActivityThread.main(ActivityThread.java:5086)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at java.lang.reflect.Method.invokeNative(Native Method)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at java.lang.reflect.Method.invoke(Method.java:515)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at dalvik.system.NativeStart.main(Native Method)

这是在我的控制器上设置对话框的方法。

    public void showDialogDesfazerAmizade(Usuario usuarioRemoverAdapter)
{

    usuarioRemover = usuarioRemoverAdapter;

    confirmacaoDesfazerAmizade = new Confirmacao(superContext,
            "Você deseja mesmo desfazer amizade com", "Desfazer amizade",
            usuarioRemover.getNome().toString());

    confirmacaoDesfazerAmizadeBtns = new ConfirmacaoBtns()
    {
        @Override
        public void positiveBtnClicked()
        {

            if (usuarioLogado != null
                    && usuarioLogado.getIdmoymer() != null
                    && usuarioRemover != null
                    && usuarioRemover.getIdmoymer() != null)
            {
                RemoveAmigoAsyncTask removeAmigoAsyncTask = new RemoveAmigoAsyncTask(
                        AmigosFragmentNovo.this, superContext, 0,
                        usuarioLogado.getIdmoymer(),
                        usuarioRemover.getIdmoymer(), usuarioRemover);
                removeAmigoAsyncTask
                        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                listaAsyncTasks.add(removeAmigoAsyncTask);
            }

        }

        @Override
        public void negativeBtnClicked()
        {
            if (confirmacaoDesfazerAmizade != null
                    && confirmacaoDesfazerAmizade.isShowing())
            {
                confirmacaoDesfazerAmizade.dismiss();
            }
        }
    };

    confirmacaoDesfazerAmizade
            .setBtnsControl(confirmacaoDesfazerAmizadeBtns);

    if (confirmacaoDesfazerAmizade != null
            && !confirmacaoDesfazerAmizade.isShowing())
    {
        confirmacaoDesfazerAmizade.show();
    }

}

这是确认自定义对话框。

public class Confirmacao extends Dialog implements android.view.View.OnClickListener {

public Context c;
public Dialog d;
public LinearLayout acaoLL, cancelarLL, perguntaLL;
private String pergunta;
private String perguntaBold;
private String tituloAcao;

private ConfirmacaoBtns btnsControl;

private TextView acaoTV;
private TextView perguntaTV;
private TextView pergunta_boldTV;

public Confirmacao(Context context, String pergunta, String tituloAcao) 
{
    super(context);
    this.tituloAcao = tituloAcao;
    if(pergunta != null)
        this.pergunta = pergunta;
    this.c = context;
}   

public Confirmacao(Context context, String pergunta, String tituloAcao, String perguntaBold) 
{
    super(context);
    this.tituloAcao = tituloAcao;
    if(pergunta != null)
        this.pergunta = pergunta;
    if(perguntaBold != null)
        this.perguntaBold = perguntaBold;
    this.c = context;
}   

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.confirmacao);
    getWindow().setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));  

    acaoLL = (LinearLayout) findViewById(R.id.confirmacao_acao);
    cancelarLL = (LinearLayout) findViewById(R.id.confirmacao_cancelar);
    perguntaLL = (LinearLayout) findViewById(R.id.pergunta_layout);

    Typeface openSansRegular = Typeface.createFromAsset(c.getAssets(), Font.OPENSANS_REGULAR);
    Typeface openSansBold = Typeface.createFromAsset(c.getAssets(), Font.OPENSANS_BOLD);

    acaoTV = (TextView)findViewById(R.id.confirmacao_acao_tv);
    acaoTV.setTypeface(openSansRegular);

    perguntaTV = (TextView)findViewById(R.id.pergunta);
    perguntaTV.setTypeface(openSansRegular);

    pergunta_boldTV = (TextView) findViewById(R.id.pergunta_bold);

    if(perguntaBold != null)
    {   
        pergunta_boldTV.setTypeface(openSansRegular);
        pergunta_boldTV.setText(Html.fromHtml("<b>" + (perguntaBold) + "</b>" + "?"));
    }else
        pergunta_boldTV.setVisibility(View.GONE);

    acaoTV.setTypeface(openSansRegular);
    perguntaTV.setTypeface(openSansRegular);

    if(this.tituloAcao!=null)
        acaoTV.setText(this.tituloAcao);
    if(this.pergunta!=null)
        perguntaTV.setText(this.pergunta);
    else
        perguntaLL.setVisibility(View.GONE);

    acaoLL.setOnClickListener(this);
    cancelarLL.setOnClickListener(this);

    showDialogOnScreenBottom();
}

private void showDialogOnScreenBottom() {
    Window window = getWindow();
    WindowManager.LayoutParams wlp = window.getAttributes();

    wlp.width = LayoutParams.MATCH_PARENT;
    wlp.height = LayoutParams.MATCH_PARENT;
    wlp.gravity = Gravity.BOTTOM;
    wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
    window.setAttributes(wlp);      
}

public void setBtnsControl(ConfirmacaoBtns btnsControl) 
{
    this.btnsControl = btnsControl;
}

@Override
public void onClick(View v) 
{
    switch (v.getId()) {
    case R.id.confirmacao_acao:
    {
        if(btnsControl!=null)
            btnsControl.positiveBtnClicked();
        dismiss();


        break;
    }
    case R.id.confirmacao_cancelar:
    {
        if(btnsControl!=null)
            btnsControl.negativeBtnClicked();
        dismiss();
        break;
    }
    default:
        break;
    }
    dismiss();
}

public void negativeButtonGone()
{
    cancelarLL.setVisibility(View.GONE);
}

public interface ConfirmacaoBtns
{
    public void positiveBtnClicked();
    public void negativeBtnClicked();

}   
}

3 个答案:

答案 0 :(得分:1)

问题是上下文,因为Fede Bucich和Don Chakkappan回答,但是不可能将活动的名称引用为“ActivityName.this”,因为该方法位于片段内。所以正确的答案是使用getActivity()而不是Context:

confirmacaoDesfazerAmizade = new Confirmacao(getActivity(),
        "Você deseja mesmo desfazer amizade com", "Desfazer amizade",
        usuarioRemover.getNome().toString());

答案 1 :(得分:0)

我不知道您的superContext变量是什么,但请尝试发送MyActivityName.this作为上下文。

您还可以尝试在活动开始时为MyActivityName.this变量分配superContext

答案 2 :(得分:0)

问题在于你的Context进入确认对话框。试试这个

confirmacaoDesfazerAmizade = new Confirmacao(CurrentActivity.this,
            "Você deseja mesmo desfazer amizade com", "Desfazer amizade",
            usuarioRemover.getNome().toString());

对于片段getActivity()而不是CurrentActivity.this