前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TII--Handler的使用

TII--Handler的使用

作者头像
张风捷特烈
发布2018-09-29 11:22:48
3000
发布2018-09-29 11:22:48
举报

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


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

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

handler1.png

1、准备工作:
代码语言:javascript
复制
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)凭什么给你(其他线程)乱摸(修改...),你又不是我女朋友。

代码语言:javascript
复制
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

二、Handler的使用

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

代码语言:javascript
复制
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:空消息要有一个标识
代码语言:javascript
复制
private int SEND_ID = 0;
1-2:发送空消息:
代码语言:javascript
复制
new Thread() {
     @Override
     public void run() {
         mHandler.sendEmptyMessage(SEND_ID);
     }
 }.start();
1-3:Handler根据接收的标识执行动作
代码语言:javascript
复制
 private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == SEND_ID) {
                mIdTvHandler.setText("你身上有米粒!");
            }
        }
    };
2.延迟空消息
代码语言:javascript
复制
 mHandler.sendEmptyMessageDelayed(SEND_ID,1000);
 //或:mHandler.sendEmptyMessageAtTime(SEND_ID, SystemClock.uptimeMillis()+1000);

延迟.gif

3.同样sendMessage延迟类似:
代码语言:javascript
复制
mHandler.sendMessageDelayed(msg, 1000L);
mHandler.sendMessageAtTime(msg, SystemClock.uptimeMillis()+1000);

三、post发送消息:传入Runnable

post.png

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

代码语言:javascript
复制
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
代码语言:javascript
复制
if (mRunnable != null) {
    mHandler.removeCallbacks(mRunnable);
}

四、Activity方法:runOnUiThread

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

runout.png

代码语言:javascript
复制
new Thread(){
    @Override
    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mIdTvHandler.setText("你身上有米粒!");
            }
        });
    }
}.start();

五、Handler和Timer结合
代码语言:javascript
复制
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]你的喜欢与支持将是我最大的动力

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.09.08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、还是以最经典的:子线程更新UI来引入吧
    • 1、准备工作:
      • 2.结果:
      • 二、Handler的使用
      • 二、发送空消息
        • 1.空消息
          • 1-1:空消息要有一个标识
          • 1-2:发送空消息:
          • 1-3:Handler根据接收的标识执行动作
        • 2.延迟空消息
          • 3.同样sendMessage延迟类似:
          • 三、post发送消息:传入Runnable
            • 移除callback
            • 四、Activity方法:runOnUiThread
            • 五、Handler和Timer结合
            • 后记、
              • 1.声明:
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档