用handler/thread来做定时器
2017-05-01
编程
刚开始接触android编程的时候,是大三.那时候在做精益防伪的演示版App,网络协议用的是socket.
使用socket的时候,编译器告诉我,需要在新线程中来使用socket操作.
于是乎,就学习了Thread的使用.
当时觉得Thread好像还是蛮简单的.在thread里面搞一个runnable,在runnable里面跑代码块,用start(),stop()来控制线程的开始和结束.
之后在thread中操控了ui,就闪退了.因为UI只能在主线程中去操作.这iOS就牛逼了,即使不在主线程中去操作,他也不会闪退.他会自动的在主线程中去渲染.
分界线
言归正传,后面上课,老师让我们用thread来做一个定时器,在主线程中显示一个数字,在另一个线程中定时增加数字.
这玩意儿是来学习Thread和Handler的.
之后需要用到定时器的地方我都用Thread来实现了~
然而
Thread不是很安全.而且,对于不同的手机厂商,不同的ROM,对thread的操作也是不一样的.
Thread workingThread = new Thread(new Runnable() {
@Override
public void run() {
while (isWorking) {
byte[] wantSend = sendingData();
if (wantSend == null || mainCharacteristic == null || mainGatt == null) {
dataPointer = 0;
isWorking=false;
workingThread.interrupt();
} else {
mainCharacteristic.setValue(wantSend);
mainGatt.writeCharacteristic(mainCharacteristic);
if (dataPointer == 0 && dataStack.size() > 0) {
try {
Thread.sleep(gifInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
Thread.sleep(baseInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
某些手机上,这个thread是停不下来的.在某些手机上,这个thread是无法重启的.在某些手机上,这个thread是无法中断的.
这就意味着,某些手机上,炫轮app只能发送一次图片;在某些手机上,炫轮app无法显示附近的蓝牙.
查了一些资料,我才发现thread,的很多接口都被废弃了,而且非常不安全,很容易出现锁死卡死的情况.
于是我去检查了很早很早很早的炫轮app.发现是用延迟来做定时器功能的.
于是我把Runnable提取出来了:
Runnable sendingRunnable=new Runnable() {
@Override
public void run() {
if (isWorking) {
byte[] wantSend = sendingData();
if (wantSend == null || mainCharacteristic == null || mainGatt == null) {
dataPointer = 0;
isWorking=false;
} else {
mainCharacteristic.setValue(wantSend);
mainGatt.writeCharacteristic(mainCharacteristic);
if (dataPointer == 0 && dataStack.size() > 0) {
mHandler.postDelayed(sendingRunnable,gifInterval);
} else {
mHandler.postDelayed(sendingRunnable,baseInterval);
}
}
}
}
};
用Handler的postDelayed来做延迟执行,这竟然就解决了前面所有的问题!
原因,我还要好好查些资料,再来补充.下次更新!