为什么要使用Handler?
在线程中,主线程用于更新UI,而子线程并不能更新UI,但是主线程又不能进行耗时操作,由此,Handler的作用在这里体现出来了,通过使用Handler完成主线程和子线程信息的传递,从而达到效果;
什么是Handler
Handler是Android SDK中处理异步类消息的核心类,其作用是让子线程通过与UI通信来更新UI界面
总结起来也可以这样说:
1.当应用程序启动时,会初始化一个UI线程
2.UI线程中创建了Looper,所以是一个循环工作线程
3.创建Looper时,Looper会创建一个MessageQueue
4.UI中的Looper会不断从MessageQueue中取出消息
什么是Looper?什么是MessageQueue?
Looper是一个取出消息的人,而MessageQueue则是放置消息的一个箱子。
要点 1:在Androidz中创建出普通线程默认是没有消息循环的,run方法执行完毕,线程也就结束。
2:如果让线程不停的循环工作,可以使用Looper,将普通线程变成循环工作线程。
3:当创建Looper时,将会自动创建出MessageQueue。
4:一个线程中只会存在一个Looper和一个MessageQueue。
5:当MessageQueue中有消息时,Looper将从MessageQueue中取出消息。
Handler怎么用?
举个倒计时的例子:
MainActivity代码:
new Thread(new Runnable() { @Override public void run() { for (i=s;i>=0;i--){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } str = Integer.toString(i); handler.sendEmptyMessage(1); /* runOnUiThread(new Runnable() { @Override public void run() { } });*/ if(i==0){ break;
用一个MessageQueue来接收
private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); textView.setText(str); } };
案例解析——倒计时Demo
子线程完成工作之后通过Handle发送消息到MessageQueue里面,Looper将消息取出给主线程处理
MainActivity完整代码:
import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.Editable; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private TextView downloadtv; private Button downloadbtn; private EditText editText; private TextView textView; int i; int s; String str; private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); textView.setText(str); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindID(); } private void bindID() { downloadtv=findViewById(R.id.xiazai_tv); downloadbtn=findViewById(R.id.xiazai_bt); textView=findViewById(R.id.xiazai_tv1); editText=findViewById(R.id.xiazai_et); downloadbtn.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.xiazai_bt: String a=editText.getText().toString(); s=Integer.valueOf(a).intValue(); new Thread(new Runnable() { @Override public void run() { for (i=s;i>=0;i--){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } str = Integer.toString(i); handler.sendEmptyMessage(1); /* runOnUiThread(new Runnable() { @Override public void run() { } });*/ if(i==0){ break; } } } }).start(); break; default: break; } } }