Hander原理&&handler的使用&&CalledFromWrongThreadException的原因

一: 原理

不同线程之间的变量是共享的,可以同时进行操作,这造成数据不同步,出现CalledFromWrongThreadException的错误的原因就是进行网络访问和进行UI操作时主,子线程回调错误,可以使用handler自动进行主子线程切换解决。handler是在主线程中创建,则主线程与子线程都可以访问handler里面的数据,在子线程中的message,Bundle,what 被发送到主线程中的messageQueue进行存储,而主线程中的Looper类会执行Loop方法中的一个死循坏把messageQueue中的数据进行执行,如果有message就执行,调用target的dispatchMessage方法回调handlerMessage方法执行数据,否则就一直等待。

下面是胡老师讲解时的图,基本原理流程是子线程发送消息(message)到messageQueue,通过Looper的message的target调用dispatchmessage回调mhandler进行处理数据与操作

在这里插入图片描述
handler可以帮助我们进行主线程与子线程的切换,子线程与子线程的切换

二:handler的使用

案例一:下面以实现一个计时器为例
handler代码(放入public class Main2Activity extends AppCompatActivity 里面,onCreate外面)

 Handler mhander =new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            if(time>0){
                button.setText(time+"秒后可继续发送短信");
                time--;
                mhander.sendEmptyMessageDelayed(1,1000);
            }else {
                button.setText("重新发送");

            }

        }
    };
    int time=10;

onCreate函数的监听事件

 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                time=10;
                mhander.sendEmptyMessage(1);
            }
        });

案例二:如果是传值的话,使用代码如下

Handler mhander =new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

          
            //主线程操作UI进行赋值
            String grade =msg.getData().getString("grade");
            String classname =msg.getData().getString("classname");
            textView11.setText("年级:"+ grade);
            textView22.setText("班级:"+classname);
        }
    };

onCreate函数的

				    Message message =new Message();
                    message.what=1;
                    Bundle bundle=new Bundle();
                    bundle.putString("grade",grade);//KEY+数据,进行包装数据
                    bundle.putString("classname",classname);
                    message.setData(bundle);将数据包装进message
                    mhander.sendMessage(message);//将值传送过去
                    
发布了57 篇原创文章 · 获赞 5 · 访问量 2799

猜你喜欢

转载自blog.csdn.net/qq_43520913/article/details/105535573