用handler/thread来做定时器

刚开始接触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来做延迟执行,这竟然就解决了前面所有的问题!

原因,我还要好好查些资料,再来补充.下次更新!