1.如何实现子线程与子线程的交互(Timer,加Hanlder 实现)
2.另外线程的run方法与start方法的区别
子线程的交互
class MyThread extends Thread {
public Handler mHandler;
@Override
public void run() {
//每一个线程都只能有一个Looper 对象
// 不实例化则不能实例化Handler;
Looper.prepare();
//1000ms之后发送一个空的消息
new Timer().schedule(new TimerTask() {
@Override
public void run() {
myThread2.mHandler2.sendEmptyMessage(0x123);
Log.i("TAG","### current MyThread2 = " + Thread.currentThread().getName());
}
},1000);
//无线循环读取消息
Looper.loop();
}
}
class MyThread2 extends Thread {
public Handler mHandler2;
@Override
public void run() {
Looper.prepare();
mHandler2 = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x123) {
Log.i("TAG", "### receive come from MyThread --- This is Test ! good");
Log.i("TAG","### current MyThread2 = " + Thread.currentThread().getName());
}
}
};
Looper.loop();
}
}
以上就是两根子线程的代码
最后贴上调用代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
myThread = new MyThread();
myThread.start();
myThread2 = new MyThread2();
myThread2.start();
}
打印log如下:
结论:
一根线程只能有一个looper对象,所以在子线程里面实例化Handler必需要跟Looper关联,所以我们只需要记住在子线程里面实例化Hanlder对象需要调用Looper.prepare()准备,并且最后无线循环的读取消息Looper.loop(),随后借助handler收发信息即可;
- -
run方法与start 区别
另外log里面也显示两根子线程确实是在子线程里面 ui线程在main线程里面,好我修改代码如下
class MyThread extends Thread {
public Handler mHandler;
@Override
public void run() {
Log.i("TAG", "### current MyThread = " + Thread.currentThread().getName());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("TAG", "### current Main = " + Thread.currentThread().getName());
// 调用方法修改为调用run 方法
myThread = new MyThread();
myThread.run();
// myThread = new MyThread();
// myThread.start();
// myThread2 = new MyThread2();
// myThread2.start();
}
我们运行一下看看log;
我在MyThread的run 方法里面打印了log,获取当前的线程名字,如上;
是不是很奇怪,明明就是在子线程里面为什么变成了main线程?
修改代码:
myThread = new MyThread();
myThread.start();
打印log如下:
可以看到对比结果很明显,一个在子线程另外一个在main线程;
结论:
通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。
然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,
Run方法运行结束,此线程终止,而CPU再运行其它线程,
而如果直接用Run方法,这只是调用一个方法而已,程序中依然只有主线程,这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。