Unable to add window——token android.os.BinderProxy@196e65b8 is not valid;is your activit is running?

Caused by: android.view.WindowManager$BadTokenException:Unable to add window——token android.os.BinderProxy@196e65b8 is not valid;is your activit is running?

在这里插入图片描述

  1. 分析日志,根据日志可知原因:无法加载一个window,一个Binder 代理无效(BinderProxy),至于什么是Binder代理(BinderProxy)这里就不解释了。
          那这个日志到底是什么意思呢那这个日志到底是什么意思呢?
    其实也就是说,当你要显示一个View1,而此时View1所依赖的View不存在,或者finish了就会出现这样的问题,但是所依赖的View不存在的情况有很多种,这个原因,自己多debug 看看,具体为什么所依赖的View 不存在了。下面我复现一下我出现的这个问题情形。

1.1、主Activity

1.1.1、SinglerTonActivity .java

public class SinglerTonActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singler_ton);
    }
    public void into(View v){ //此方法定义在下面的xml中
        Intent intent = new Intent(SinglerTonActivity.this, A_Activity.class);
        startActivity(intent);
    }
}

1.1.2、activity_singler_ton.xml



    

1.2、从SinglerTonActivity跳转到A_Activity

1.2.1、A_Activity.java

public class A_Activity extends AppCompatActivity {
    private SingerTonDialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a_);
        dialog = SingerTonDialog.getInstance(A_Activity.this);
    }
    public void showDialog(View v){
        dialog.show();
    }
}

1.2.2、activity_a_.xml



    

1.3、 弹出的Dialog

1.3.1、SingerTonDialog.java

public class SingerTonDialog {
    private Dialog dialog;
    public volatile static SingerTonDialog progress;
    public static SingerTonDialog getInstance(Context context){
        if (progress == null)
            synchronized (AlertDialog.class){
                if (progress == null)
                    progress = new SingerTonDialog(context);
            }
        return progress;
    }
    public SingerTonDialog(Context context){
        View v = LayoutInflater.from(context).inflate(R.layout.singler_ton_dialog,null);
        dialog = new Dialog(context,R.style.refresh_dialog);
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.FILL_PARENT);
        dialog.setContentView(v, params);
    }

    public SingerTonDialog show(){
        dialog.show();
        return progress;
    }
    public void dismiss(){
        dialog.dismiss();
    }
}

1.3.2、singler_ton_dialog.xml



    
    

到此,代码片段贴完了。下面我们简单的分析分析这个依赖的View(此处为Activity)为什么空了

  • 1、我们首先从SinglerTonActivity(主Activity)跳转到 A_Activity,

  • 2、在 A_Activity中通过点击事件,弹出一个dialog

    • 根据Activity的生命周期,每次跳转到 A_Activity,都会执行onCreate方法,那么就会去创建SingerTonDialog实例(对象),然后传入Context。
    • 然后通过 SingerTonDialog 对象的 show方法弹出这个dialog。
  • 问题:按照这个思路走,SingerTonDialog 所依赖的View (A_Activity)不是每次走了onCreate 等方法吗,既然走完了Activity的生命周期,按理说Activity应该存在啊,那么为什么此处出现了这个问题?我的Activity不存在?不应该,肯定的存在的。没错,我是这样的想的,奇怪,去趟WC。

  • 回来突然想起来了,手残也SingerTonDialog的时候,把它写成了单例模式,而这个单例写的对于java来说,问题不大,但在此处问题却是致命。

  • 看看SingerTonDialog这个类,我们用static volatile 关键字去修饰了这个对象,并且还是双重验证。

  • 那么你看出来了吗?问题就出现在这个 static volatile 这,或者说 static 这,由于我用了static 修饰了这个类,那么SingerTonDialog 将会一直存在(至于什么时候GC回收,会不会回收等问题在此不解释)。

  • 那么第一次创建SingerTonDialog这个对象的时候传进来的Context(Binger代理-BinderProxy@196e65b8)去创建Dialog,且创建后悔一直存在,在下一次在此创建的时候,由于这个对象一直存在,所以下一次就不会用新传进来的Context去创建Dlialog。

  • 而是用上一次的Context去创建,但是上一次的Activity 不存在了,所以第二次开始,当点击事件弹出这个Dialog的时候就会出现这个问题。到此,原因应该解释清楚了,那么此情景解决办法应该也知道了吧,就不在此说了。

    如有说错,欢迎大佬留言指正,权当记录错误,在此相互学习学习

你可能感兴趣的:(Unable to add window——token android.os.BinderProxy@196e65b8 is not valid;is your activit is running?)