因为学过Java,所以对线程和进程并不陌生,在Android中线程是一样的写法都是继承Tread或者Runable用start回调run方法,只是用法上有些许区别。
首先是Handler这个类,API中说A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue.
其实就是用于线程之间通讯,UI主线程不允许其他线程对View进行操作,在主线程中建立Handler包含一个子线程,子线程利用主线程的Handler消息队列给主线程发送message,Handler本身带着一个线程,是异步回调。下图表示Handler用于子线程向主线程发送message
Handler实例:子线程每隔一段时间就发送msg给主线程,Handler更新控件,实现了一个显示60s递减的button
代码:
public class MainActivity extends Activity {
private int count=60;
private Button mBtn_DESC;
private Handler handler=new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 0:
String time= (String) msg.obj;
mBtn_DESC.setText(time);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn_DESC= (Button) findViewById(R.id.button_DESC);
mBtn_DESC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
while (count>0){
count--;
Message msg=handler.obtainMessage();//这个方法实现有Message的对象就回收,没有就创建
msg.obj=count+"秒";//强制转换成了秒
msg.what=0;
handler.sendMessage(msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}
}
进化版:没有新建子线程,用的Handler本身包含的线程给主线程发消息
public class MainActivity extends Activity {
private int count=60;
private Button mBtn_DESC;
private Handler handler=new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){//what相当于是个标志
case 0:
count--;
mBtn_DESC.setText(count+"秒");
if (count>0){
try {
Thread.sleep(1000);//间隔1s递减
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(0);//count>0就发送一个空消息,形成循环
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn_DESC= (Button) findViewById(R.id.button_DESC);
mBtn_DESC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessage(0);
}
});
}
}public class MainActivity extends Activity {
private int count=60;
private Button mBtn_DESC;
private Handler handler=new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){//what相当于是个标志
case 0:
count--;
mBtn_DESC.setText(count+"秒");
if (count>0){
try {
Thread.sleep(1000);//间隔1s递减
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(0);//count>0就发送一个空消息,形成循环
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn_DESC= (Button) findViewById(R.id.button_DESC);
mBtn_DESC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessage(0);
}
});
}
}
主线程给子线程发送消息(用的比较少),其实就是UI线程和子线程交换位置,在UI线程中自带Looper,新建的子线程中并没有Looper需要创建一个,Handler是用的子线程的,其他的是一样的,因为发送消息耗时,所以创建了两个按钮(启动线程初始化Handler耗时,如果是一个按钮可能就会给Handler报空指针),第一个按钮只是用来启动线程,第二个按钮发送消息,控制台打印
public class MainActivity extends Activity {
private int count=60;
private Button mBtn_start;
private Button mBtn_child;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn_start= (Button) findViewById(R.id.button_start);
mBtn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {//先点击这个按钮启动线程
MyThread thread=new MyThread();
thread.start();
}
});
mBtn_child= (Button) findViewById(R.id.button_child);
mBtn_child.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {//然后点击这个按钮发送消息
handler.sendEmptyMessage(0);
}
});
}
private Handler handler;
class MyThread extends Thread{
//新建一个子线程
@Override
public void run() {
Looper.prepare();
//把Looper补上
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
Log.d("handler","主线程发过来的消息");
}
};
Looper.loop();
}
}
}