多線程
爲什麼要用Handler
- Android 中的一些耗時操作需要在子線程中去完成,Android 又規定訪問 UI 只能在主線程中進行,在子線程中訪問 UI,程序就會拋出異常。系統提供 Handler 就是爲了解決在子線程中無法訪問 UI 的矛盾。
什麼是Handler?
- 子線程通過Handler發送消息給Message,接下來Looper把取出的消息一個個發送給 主線程。
什麼是Looper?
- 相當於一個不需要休息的工人,當Handler將消息發送到MessageQueue中時,它立馬就會將發送到其中的信息取出來,一個個拿給主線程 。
什麼是MessageQueue?
Handler怎麼用?
- Handler的主要工作包含消息的發送與接收過程。消息的發送通過send方法來實現。當Handler發送了消息之後,MessageQueue裏就插入了一條消息,然後MessageQueue就會返回這條消息給Looper,Looper接收到消息之後就開始處理了,最終消息由Looper交給Handler處理,這時Handler就進入了處理消息的階段,最後經過一系列的判斷之後,就會調用handleMessage()方法了。
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==-1){
tvdown.setText("倒計時結束");
}else
tvdown.setText(msg.what+"");
}
};
new Thread(new Runnable() {
@Override
public void run() {
try {
while (cunt>0) {
Thread.sleep(1000);
cunt--;
handler.sendEmptyMessage(cunt);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
案例分析-倒計時Demo
public class downActivity extends AppCompatActivity implements View.OnClickListener{
TextView tvdown;
Button btdown;
EditText edtime;
int cunt=10;
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==-1){
tvdown.setText("倒計時結束");
}else
tvdown.setText(msg.what+"");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_down);
tvdown=findViewById(R.id.tv_down);
btdown=findViewById(R.id.bt_downlad);
edtime=findViewById(R.id.et_time);
btdown.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_downlad:
new Thread(new Runnable() {
@Override
public void run() {
try {
while (cunt>0) {
Thread.sleep(1000);
cunt--;
handler.sendEmptyMessage(cunt);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
break;
default:
break;
}
}
}