TII--Handler的使用

作者: e4e52c116681 | 来源:发表于2018-09-08 16:39 被阅读9次

Handler也是个磨人的小妖精,一次又一次的败给她


一、还是以最经典的:子线程更新UI来引入吧

场景:点击按钮新建线程,在新线程里更改TextView的值,如下图

handler1.png
1、准备工作:
public class HandlerActivity extends AppCompatActivity {
    private static final String TAG = "HandlerActivity";
    @BindView(R.id.id_tv_handler)
    TextView mIdTvHandler;
    @BindView(R.id.id_btn_change)
    Button mIdBtnChange;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        ButterKnife.bind(this);
        Log.e(TAG, "onCreate: " + Thread.currentThread().getName());//main
    }

    @OnClick(R.id.id_btn_change)
    public void onViewClicked() {
        //新建线程
        new Thread() {
            @Override
            public void run() {
                Log.e(TAG, "onViewClicked: " + Thread.currentThread().getName());//Thread-24375
                 mIdTvHandler.setText("你身上有米粒!");//更改视图
            }
        }.start();
    }
}

2.结果:
结果.png

看起来不太好,直接崩了,报了个CalledFromWrongThreadException:只有创建视图层的那个原始线程(main)才给摸他的视图。
是啊,我穿(main线程)的衣服(View)凭什么给你(其他线程)乱摸(修改...),你又不是我女朋友。

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

二、Handler的使用

人家(其他线程)就是看你衣服上有个米粒,想把他拿掉,你(main线程)还不乐意了。好吧,我找你女友(Handler)去,让她把你拿掉


public class HandlerActivity extends AppCompatActivity {
    private static final String TAG = "HandlerActivity";
    @BindView(R.id.id_tv_handler)
    TextView mIdTvHandler;
    @BindView(R.id.id_btn_change)
    Button mIdBtnChange;
    //新建Handler
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String info = (String) (msg.obj);
            //更新UI
            mIdTvHandler.setText(info);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.id_btn_change)
    public void onViewClicked() {
        new Thread() {
            @Override
            public void run() {
                //拿到一个Message对象--或直接new,但不建议new。Message.obtain()使用享元模式
                Message msg = Message.obtain();
                //将数据放到信息里
                msg.obj = "你身上有米粒!";
                //发送消息
                mHandler.sendMessage(msg);
                
                //或者
                //msg.obj = "你身上有米粒";
                ////使用handler.obtainMessage获得的msg 可以直接msg.sendToTarget()
                //msg.sendToTarget();
            }
        }.start();
    }
}
handler2.png

二、发送空消息

empty.png
1.空消息
1-1:空消息要有一个标识
private int SEND_ID = 0;
1-2:发送空消息:
new Thread() {
     @Override
     public void run() {
         mHandler.sendEmptyMessage(SEND_ID);
     }
 }.start();
1-3:Handler根据接收的标识执行动作
 private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == SEND_ID) {
                mIdTvHandler.setText("你身上有米粒!");
            }
        }
    };
2.延迟空消息
 mHandler.sendEmptyMessageDelayed(SEND_ID,1000);
 //或:mHandler.sendEmptyMessageAtTime(SEND_ID, SystemClock.uptimeMillis()+1000);
延迟.gif
3.同样sendMessage延迟类似:
mHandler.sendMessageDelayed(msg, 1000L);
mHandler.sendMessageAtTime(msg, SystemClock.uptimeMillis()+1000);

三、post发送消息:传入Runnable

post.png

通过mHandler反复发信息可做到循环

mRunnable = new Runnable() {
    @Override
    public void run() {
        index++;
        mIdTvHandler.setText("你身上有"+index+"個米粒");
        if (index < 10) {
            mHandler.postDelayed(this, 2000);
        }
    }
};

new Thread(){
    @Override
    public void run() {
        mHandler.postDelayed(mRunnable, 2000);
    }
}.start();
移除callback
if (mRunnable != null) {
    mHandler.removeCallbacks(mRunnable);
}

四、Activity方法:runOnUiThread

可见底层也是基于Handler机制的

runout.png
new Thread(){
    @Override
    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mIdTvHandler.setText("你身上有米粒!");
            }
        });
    }
}.start();

五、Handler和Timer结合

public class HandlerTimerActivity extends AppCompatActivity {
    private static final String TAG = "HandlerActivity";
    @BindView(R.id.id_tv_handler)
    TextView mIdTvHandler;
    @BindView(R.id.id_btn_change)
    Button mIdBtnChange;

    private final Timer timer = new Timer();
    private TimerTask task;
    int count = 0;

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mIdTvHandler.setText("你身上有" + count + "個米粒!");
            super.handleMessage(msg);
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        ButterKnife.bind(this);

    }

    @OnClick({R.id.id_tv_handler, R.id.id_btn_change})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.id_tv_handler:
                timer.cancel();
                
                break;
            case R.id.id_btn_change:

                task = new TimerTask() {
                    @Override
                    public void run() {
                        mHandler.sendEmptyMessage(0);
                        count++;
                    }
                };
                timer.schedule(task, 2000, 3000);
                break;
        }
    }
}


后记、

1.声明:

[1]本文由张风捷特烈原创,转载请注明
[2]欢迎广大编程爱好者共同交流
[3]个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
[4]你的喜欢与支持将是我最大的动力

2.连接传送门:

更多安卓技术欢迎访问:安卓技术栈
我的github地址:欢迎star
简书首发,腾讯云+社区同步更新
张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com

3.联系我

QQ:1981462002
邮箱:1981462002@qq.com
微信:zdl1994328

4.欢迎关注我的微信公众号,最新精彩文章,及时送达:
公众号.jpg

相关文章

  • TII--Handler的使用

    Handler也是个磨人的小妖精,一次又一次的败给她 一、还是以最经典的:子线程更新UI来引入吧 场景:点击按钮新...

  • iconfont的使用(下载使用)

    1、下载文件 2、在生命周期中引入项目 beforeCreate () { var domModule = ...

  • Gson的使用--使用注解

    Gson为了简化序列化和反序列化的过程,提供了很多注解,这些注解大致分为三类,我们一一的介绍一下。 自定义字段的名...

  • 记录使用iframe的使用

    默认记录一下----可以说 这是我第一次使用iframe 之前都没有使用过; 使用方式: 自己开发就用了这几个属...

  • with的使用

    下面例子可以具体说明with如何工作: 运行代码,输出如下

  • this的使用

    什么是this? this是一个关键字,这个关键字总是返回一个对象;简单说,就是返回属性或方法“当前”所在的对象。...

  • this的使用

    JS中this调用有几种情况 一:纯粹的函数调用 这是函数的最通常用法,属于全局性调用,因此this就代表全局对象...

  • ==的使用

    积累日常遇到的编码规范,良好的编码习惯,持续更新。。。 日常使用==用于判断的时候,习惯性将比较值写前面,变量写后...

  • this的使用

    1.默认绑定,就是函数立即执行。 函数立即执行就是指向window,但是如果是node环境,就是指向全局conso...

  • %in% 的使用

    写在前面:From 生信技能书向量难点之一:%in% 难点 (1)== 与 %in% 的区别== 强调位置,x和对...

网友评论

    本文标题:TII--Handler的使用

    本文链接:https://www.haomeiwen.com/subject/ewqlgftx.html