问题描述
我有一个长连接心跳包service,每3秒发一次,发的时候没有问题,收服务器的应答时遇到一个诡异的错误。我是新开了一个thread来运行这个runable,sendMsg()可以发给服务器,也可以打印出Log.d(TAG, 'Send HeartBeat');。但是到recvMsg()时,会抛出 InternetRunningOnMainThread异常. 我很困惑,recvMsg和sendMsg不是在同一个thread里运行吗?为什么会有异常?我的暂时的解决方案是可以在recvMsg再开一个新的thread,这样就没有异常。而且我不用心跳包机制只是单次查询应答的时候没有这个问题。
public void initAndStartHeartBeat(){ new Thread(new Runnable() {@Overridepublic void run() { if(initSocket()){startHeartBeatrunable(); }} }).start();}private Runnable heartBeatRunnable = new Runnable() { @Override public void run() {if (System.currentTimeMillis() - lastHBSendTime >= HEART_BEAT_RATE && runningHeartBeat) { Log.i(TAG, 'heartBeatRunnable Thread: ' + Thread.currentThread().getId()); sendMsg(getData2Send()); Log.d(TAG, 'Send HeartBeat'); recvMsg();}mHandler.postDelayed(this, HEART_BEAT_RATE); }};
问题解答
回答1:延时你用Handler做干嘛,就算用Handler做你也要开新的LoopThread呀,你以为Handler是怎么处理消息的,它依赖的是LoopThread的消息队列,而默认情况下,只有主线程是LoopThread线程,所以Handler默认会用它去处理消息,自然你的Runnable就跑到主线程去了。要么你就让Handler绑开新的LoopThread线程去做延时,要么就用定时器或者直接sleep去只延时。