handle
什么是handler
handler是Android SDK中处理异步消息的核心类,handler的作用是让子线程通过与UI线程通信来更新UI界面。
handler的运行机制
1.先创建一个handler对象,系统就把handle对象,UI线程和UI线程的消息队列捆绑起来。
2.当我们在线程中处理完数据后,可以通过handler对象将消息发出。
3.消息将会按先后顺序添加到消息队列中。
4.UI线程的looper不断从消息队列中取出消息刷新UI。
private Handler handler=new Handler(){
//用来接收子线程发来的消息
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int arg1=msg.arg1;
String info= (String) msg.obj;
if (msg.what==1){
downloadTips.setText("下载完成"+arg1+info
);
}
}
};
什么是looper和MessageQueue
looper是指在子线程处理耗时的工作时,担任的一个循环工作的工具,而MessageQueue就是一个主线程。looper和MessageQueue是系统自动创建的,我们不需要在创建了。当我们的应用程序启动时,我们的looper就会从MessageQueue里面取出消息,传到子线程,子线程里面可以进行耗时的工作,主线程不可以。
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
什么是Message
message是一种消息的对象。message对象可以通过handler对象的obtainMessage()
方法获得,他总共有四个属性,what属性是用来识别什么消息的,arg1和arg2都是int类型的数字,obj属性传递类型是object类型的,传递的消息是obj类型或者其他任意类型,都可以赋给obj。
Message message=handler.obtainMessage();//创建message对象
message.what=1;
message.obj="choouzhu";
message.arg1=2000;
handler.sendMessage(message);
如何使用handler
1.在UI线程中创建handle匿名内部类对象
2.在匿名内部类重写hnadleMessage方法
3.在UI线程中启动子线程
4.在线程中获得message对象
5.将需要传递的数据赋值到message对象中
6.通过handle对象的sendMessage方法发送消息到消息队列
7.在hnadleMessage方法中接收消息
说的通俗一点,就是先创建一个handler对象,然后就是发信息和捕获信息
注意点
1.在线程中只能有一个looper和MessageQueue
2.在子线程可以进行耗时的工作,主线程不可以
3.主线程可以更新UI界面
倒计时案例
首先我们需要创建一个新的activity,然后修改为LinearLayout,然后我们就需要在这个mainxml文件里面添加相应的EditText,TextView,Button控件,给它们三个控件赋上id。
<EditText
android:id="@+id/daojishi_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp" />
<TextView
android:id="@+id/daojishi_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="倒计时:"
android:textSize="30sp" />
<Button
android:id="@+id/daojishi_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="开始倒计时"
/>
然后绑定id和添加监听事件,这边需要注意的是我们要time变成全局的,因为底下需要用到。
private void bindID() {
daojishibtn=findViewById(R.id.daojishi_btn);
daojishiet=findViewById(R.id.daojishi_et);
daojishitv=findViewById(R.id.daojishi_tv);
time=Integer.parseInt(daojishiet.getText().toString());//将字符串转换成整型
接下来就是子线程了,执行run方法,记得最后要启动。我们这边使用的就是一个新方法, handler.sendEmptyMessage(i);,因为这边是整型。
new Thread(new Runnable() {
@Override
public void run() {
Message message=handler.obtainMessage();
for (int i=time;i>0;i--){
handler.sendEmptyMessage(i);
//更新UI
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
daojishitv.setText(msg.what+"");
}
};
倒计时效果图