非UI线程使用setVisibility发生的bug

1. 该方法用来设置view的可见性,需要在UI线程中设置
2. 该方法的内部实现中判断了当前view的可见性,改变时在调用invalidateSelf方法刷新自己

注意:在非UI线程中,如果调用invalidate需要刷新界面的,都会报错。如果在非UI线程中调用setVisibility方法,但visible没有改变,则不会执行invalidateSelf方法,就不会报错,只有状态改变时才会报错,所以要特别注意。

System.out.println("1 " + Thread.currentThread().getName());
Toast.makeText(getBaseContext(), "1 " + Thread.currentThread().getId(), Toast.LENGTH_SHORT).show();
txt.setVisibility(View.GONE);
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("2 " + Thread.currentThread().getName());
        // 看线程名称,已经不是主线程,但不明白为什么设置setVisibility不会报错,而Toast会报错 
        // 原因是还没有初始化界面完成,如果在线程中延迟几秒,就会发出错误了。
        //Toast.makeText(getBaseContext(), "2 " + Thread.currentThread().getId(), Toast.LENGTH_SHORT).show();
        txt.setVisibility(View.VISIBLE);
    }
}).start();

Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View arg0) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("3 " + Thread.currentThread().getName());
                // txt.setVisibility(View.VISIBLE); // 和上次的visible相同,则不发生异常
                txt.setVisibility(View.GONE); // 和上次的visible不相同,则发生异常 
            }
        });
        thread.start();
    }
});


你可能感兴趣的:(setVisibility)