开启线程的三种方式:
- 继承Thread父类
new Thread(){
@Override
public void run() {
//需要在子线程中处理的逻辑
}
}.start();
//new一个接口或者一个类,在括号就没可以直接实现里面的方法,联想setOnClickListener
// 通过继承线程类实现
new myThread().start();
// Thread是一个类,必须继承
public class myThread extends Thread {
@Override
public void run() {
super.run();
// 写子线程中的操作
}
}
- 实现Runable接口
new Thread(new Runnable() {
@Override
public void run() {
//需要在子线程中处理的逻辑
}
}).start();
// 2、通过实现Runnable接口
Thread t = new Thread(new myRunnable());
t.start();
// Runnable是一个接口,需要实现
public class myRunnable implements Runnable {
@Override
public void run() {
// 写子线程中的操作
}
- 睡眠
sleep阻塞
Thread.sleep(times)使当前线程从Running状态放弃处理器进入Block状态,休眠times毫秒,再返回Runnable状态。
Thread.sleep(1000);
想不懂的话,点击去看一下Thread的源码,发现Thread也是实现了Runable接口,run方法是实现接口的方法,所以自己声明一个Runable对象的时候,是一定要实现run方法,还有我上面提到的new Thread(){} 可以直接在{}中实现它的方法,但是不实现start也是直接开启一个线程,但是为什么要实现呢,因为我们需要在子线程里干点什么事情。
注意:
针对上面几种创建子线程的方式,一般推荐使用Runable,一个类如果使用继承的方式,一般都是要加强或者修改,因此如果没有必要重写Thread类中的其他方法,这种情况下最好采用实现Runable接口的方式。
Timer TimerTask schedule 三者关系,和线程有关系吗?
基本定义
Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行执行指定的计划任务,可以指定执行一次或者反复执行多次。(其实就是和new Thread类似)
TimerTask是一个实现Runnable接口的抽象类,代表一个可以被Timer执行的任务(其实就是和我们前面继承自Runnable接口实现的类类似,只是通过Timer开启子线程需要调用schedule函数,不是直接new Thread()传参数就行)
Timer在Android开发中的应用
应用到了WelcomeActivity跳过闪屏界面:
代码如下:
//第一步创建一个TimerTask的实现类
public class BaseTimerTask extends TimerTask {
private ITimerListener mITimeListener = null;
public BaseTimerTask(ITimerListener timerListener) {
this.mITimeListener = timerListener;
}
@Override
public void run() {
if (mITimeListener != null) {
mITimeListener.onTimer();
}
}
}
//第二步实现类中声明一个接口,用于主线程welcomeActivity更新UI
public interface ITimerListener {
void onTimer();
}
//第三步,WelcomeActivity中开启Timer的调用
private void initTimer() {
mTimer = new Timer();
final BaseTimerTask task = new BaseTimerTask(this);
mTimer.schedule(task, 0, 1000);
}
//第四步不要忘记ITimerListener接口的回调,实现这个接口
public class WelcomeActivity extends BaseActivity implements ITimerListener
//实现,注意主线程中更新UI
@Override
public void onTimer() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (tvTimerWelcome != null) {
tvTimerWelcome.setText("跳过" + mCount);
mCount--;
if (mCount < 0) {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
checkSkip();
}
}
}
}
});
}
代码分析:
- new一个TimerTask的子类,重写run方法来指定具体的任务,在这个例子里,我用匿名内部类的方式来实现了一个TimerTask的子类
- new一个Timer类,Timer的构造函数里会起一个单独的线程来执行计划任务。jdk的实现代码如下:
public Timer() {
this("Timer-" + serialNumber());
}
public Timer(String name) {
thread.setName(name);
thread.start();
}
- Timer在主线程外开启一个单独的子线程执行任务时候,调用的是schedule函数
- schedule函数中每个参数的意义,参数一要执行的任务,参数二,参数3,执行时间间隔,每一秒钟执行一次,到达下面的条件之后,回调用mTimer取消。
- 任务完成后的Timer线程结束采用cancle,并且=null
- mTimer.schedule(task, 0, 1000);在没有取消单独的子线程之前,每隔一秒会执行任务中的run方法,回调我们自己写的接口做一些操作。
注意事项:
- 每一个Timer仅对应一个唯一的线程
- Timer不保证任务执行一定准确
- Timer类线程安全