Handler
1.什么是Handler?
当我们用子线程处理耗时的操作,在操作完成后需要更新UI,这时就会需要用到Handler,Handler能帮我们很容易的把任务(在子线程处理)切换回它所在的线程。简单理解,Handler就是解决线程和线程之间的通信的。
2.什么是looper和MessageQueue?
当子线程处理完耗时操作,发送的消息会以排队的形式存在MessageQueue中,当MessageQueue中有消息时,Looper会将消息取出,通过handleMessage传递给主线程(注:一个线程中只会存在一个MessageQueue和Looper)
3.什么是Message?
Message对象即消息对象,子线程将需要传递到UI的线程的信息放入Message对象中,Message对象可以通过Handler对象的obtainMessage方法获得。(注:Message有两种方式获得(1)new Message (2) obtainMessage)
Message的属性: what属性:int型的消息码,接收方用来识别是什么消息
arg1,arg2: int型,如果传递的消息仅仅是整形数字,可以将数字赋值给arg1,arg2
obj属性: Object类型,如果传递的消息是String或任意类型时,可将数据赋值给obj属性
sendToTarget方法: 将消息发送给指定的Handler对象
4.如何使用Handler?
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){ downloadTV.setText("下载完成"+arg1+info); } } };
downloadBTN.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { downloadTV.setText("正在下载"); //启动子线程,模拟5秒下载过程。 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } Message message=handler.obtainMessage();//创建Message对象 message.what=1; message.arg1=2; message.obj="HELLO"; handler.sendMessage(message); } }).start(); } });
如上代码所示,第一步创建Handler,第二步,通过Message传递消息给Handler,第三部,接受消息。
5.倒计时案例举例。
在xml文件中完成如上布局,将相应的Button,EditText,TextView,赋予id。
java中的代码如下:
package com.example.handlerdemo; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class ClockActivity extends AppCompatActivity { private EditText settingET; private TextView windowTV; private Button clickBtn; private int time; private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); windowTV.setText(msg.what+""); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_clock); bindID(); clickBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { time=Integer.parseInt(settingET.getText().toString());//将字符串转换成整形 new Thread(new Runnable() { @Override public void run() { for (int i=time;i>0;i--){ //更新UI handler.sendEmptyMessage(i); try{ Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }); } private void bindID() { settingET=findViewById(R.id.setting_et); windowTV=findViewById(R.id.window_tv); clickBtn=findViewById(R.id.click_btn); } }
如条目四所说,Handle传值的三个步骤中嵌入一个for语句,实现倒数功能,即可完成。注意what只能传递int型值