关于Handler的简单应用

本文介绍了Android中Handler的使用,包括为何使用Handler解决UI线程更新问题,Handler的工作原理,涉及MessageQueue和Looper的角色。此外,还给出了一个倒计时代码示例,展示Handler如何在子线程与主线程间同步通信。
摘要由CSDN通过智能技术生成

Handler

为什么要用handler

学习handler之前我们线模拟一个简单的视频下载,当我们在模拟视频下载的更新操作中,需要按下开始下载按钮,需要视频中准备下载的字幕立刻转换成正在下载。这里补充i一下开启线程的两个方法
1.继承Threadle类
2.实现runnable接口
这里需要用到线程来实时的对按钮的动作进行判断,首先布局文件给一个button和text view

在activity中添加单击事件,在单击事件中,开启一个线程如下:

public void onClick(View v) {
switch (v.getId()){
case R.id.download_btn:
new Thread(new Runnable() {    //主线程
@Override
public void run() {                    //子线
try {

Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
download_tv.setText("正在下载");
}
}).start();
break;

报错: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
大概意思:只有主线程可以更新UI
主线程:ui线程,UI的更新必须放在主线程中。

引出handler

Handler: 是Android SDK中处理异步消息的核心类:两个线程同步通信

作用: 让子线程通过handler更新UI,不只是这一个作用

工作原理:子线程通过handler.setMessage发送到Message Queue,然后由looper取出消息 给主线程

什么是MessageQueue :

MessageQueue的中文翻译是消息队列,顾名思义,它的内部存储了一组消息,以队列的形式对外提供插入和删除的工作。虽然叫消息队列,但是它的内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息。它只是用来存储消息,而并不能处理消息,Looper就填补了这个功能。

Looper:

在MessageQueue里存储了消息之后,Looper就会以无限循环的形式去查是否有新消息,如果有的话就去处理消息,否则就是一直等待着

这里写图片描述
一个线程中只会存在一个Looper和MessageQueue
UI线程会自动初始化Message Queue和looper
初始化Handler
导包:os

private Handler handler=new Handler(){
@Override
//接收子线程更新消息
public void handleMessage(Message msg) {
super.handleMessage(msg);
download_tv.setText("正在下载");
}
};

public void onClick(View v) {
switch (v.getId()){
case R.id.download_btn:
new Thread(new Runnable() {
@Override
public void run() {
try {

Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(1);//接收int类型的数字
}
}).start();
break;
}
}

倒计时代码:

package com.example.xiaozhen.mynewapplication;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class DownloadActivity extends AppCompatActivity implements View.OnClickListener {
private TextView download_tv,download_tvtime;
private Button download_btn;
private EditText download_et;

private int x;
private Handler handler = new Handler() {
@Override
//接收子线程更新消息
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==-1){
download_tvtime.setText("倒计时结束");
}else{
//直接将整型的转换成字符串类型的
download_tvtime.setText(msg.what+"");
}

}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
init();
download_btn.setOnClickListener(this);
download_et.setOnClickListener(this);
}

private void init() {
download_btn = (Button) findViewById(R.id.download_btn);
download_tv = (TextView) findViewById(R.id.download_tv);
download_et = (EditText) findViewById(R.id.download_et);
download_tvtime= (TextView) findViewById(R.id.download_tvtime);

}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.download_btn:
new Thread(new Runnable() {
@Override
public void run() {
     //首先得到download——et所录入的时间,因为得到的是string类型的,所以要转成int类型的
     //因为handler.sendEmptyMessage()这个方法只能接收int类型的
for (int x=Integer.parseInt(download_et.getText().toString());x>0;x--) {
//这里所需要传递的int就是所需要接收的倒计时数字
handler.sendEmptyMessage(x);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
handler.sendEmptyMessage(-1);
}

}).start();
break;
}
}
}

“`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值