• android 细节之 AndroidRuntimeException:This message is already in use


    今天在做项目处理消息队列的时候。遇到了这样一个问题。一个异常。AndroidRuntimeException:This message is already in use。

    我当时的详细业务需求情境为。想要跟硬件联动的时候。保持在一定时间内仅仅有一个操作。假设不idle。就又一次发送消息,而且此消息应该delay一段时间,就是TIMEDELAY。

    详细出现错误的代码例如以下:

    private class ChargecaseServiceHandler extends Handler {
    
    		public ChargecaseServiceHandler(Looper looper) {
    			super(looper);
    		}
    
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			Command command = new Command();
    			command.command = msg.what;
    
    			if (msg.obj != null) {
    				command.data = (Bundle) msg.obj;
    			}
    			if (sIsLoopBleServiceReady) {
    				if (isIdle) {
    					switch (msg.what) {
    
    					case MESSAGE_KILL:
    						stopSelf();
    
    						break;
    					case MESSAGE_START_BLE_SCAN:
    						startBLEScan();
    						break;
    					case MESSAGE_CONNECT:
    						connect(command.data);
    						break;
    					case MESSAGE_DISCONNECT:
    						attemptDisconnect();
    						break;
    					case MESSAGE_RELEASE_DEVICE_ID:
    						clearData();
    						break;
    					case MESSAGE_INITIALIZE:
    						initialize();
    						break;
    					case MESSAGE_RESET_BLE:
    						resetBleController();
    						break;
    					case MESSAGE_STARTUP:
    						startup();
    						break;
    					case MESSAGE_REGISTER:
    						register(command.data);
    						break;
    					case MESSAGE_UNREGISTER:
    						unregister(command.data);
    						break;
    					case MESSAGE_RECONNECT:
    						reconnect();
    						break;
    					case MESSAGE_ADDCARD:
    						addCard(command.data);
    						break;
    					case MESSAGE_GETCARDLIST:
    						getCardList(command.data);
    						// removeMessages(MESSAGE_GETCARDLIST);
    						break;
    					case MESSAGE_GETCARDDETAIL:
    						getCardDetail(command.data);
    						break;
    					case MESSAGE_REMOVECARD:
    						removeCard(command.data);
    						break;
    					case MESSAGE_CHECK_BATTERY:
    						checkBattery();
    						break;
    					case MESSAGE_SET_DEFAULT_CARD:
    						setDefaultCard(command.data);
    						break;
    					case MESSAGE_ZAP_CARD:
    						zapCard(command.data);
    						break;
    					case MESSAGE_SET_LOCK_TIME:
    						setLockTimer(command.data);
    					}
    				} else {
    					sServiceHandler.sendMessageDelayed(msg, TIMEDELAY);
    				}
    			} else {
    				Toast.makeText(getApplicationContext(),
    						"Starting ble for you.", Toast.LENGTH_SHORT).show();
    			}
    		}
    	}

    然后上网搜了一下。发现实际上说明发送的消息正在消息队列中。表示如今正在被使用。


    參考大神的博客后。(大神博客请移步http://blog.csdn.net/aa4790139/article/details/6579009)


    发现解决方法:解决的方法又一次创建一个新的消息。发送过去就ok啦!问题解决。


    于是我就准备new 一个 message或是obtain 一个message。而不是直接send这个message来进行delay。但是依旧出错,二次出错的代码例如以下:

    private class ChargecaseServiceHandler extends Handler {
    
    		public ChargecaseServiceHandler(Looper looper) {
    			super(looper);
    		}
    
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			Command command = new Command();
    			command.command = msg.what;
    
    			if (msg.obj != null) {
    				command.data = (Bundle) msg.obj;
    			}
    			if (sIsLoopBleServiceReady) {
    				if (isIdle) {
    					switch (msg.what) {
    
    					case MESSAGE_KILL:
    						stopSelf();
    
    						break;
    					case MESSAGE_START_BLE_SCAN:
    						startBLEScan();
    						break;
    					case MESSAGE_CONNECT:
    						connect(command.data);
    						break;
    					case MESSAGE_DISCONNECT:
    						attemptDisconnect();
    						break;
    					case MESSAGE_RELEASE_DEVICE_ID:
    						clearData();
    						break;
    					case MESSAGE_INITIALIZE:
    						initialize();
    						break;
    					case MESSAGE_RESET_BLE:
    						resetBleController();
    						break;
    					case MESSAGE_STARTUP:
    						startup();
    						break;
    					case MESSAGE_REGISTER:
    						register(command.data);
    						break;
    					case MESSAGE_UNREGISTER:
    						unregister(command.data);
    						break;
    					case MESSAGE_RECONNECT:
    						reconnect();
    						break;
    					case MESSAGE_ADDCARD:
    						addCard(command.data);
    						break;
    					case MESSAGE_GETCARDLIST:
    						getCardList(command.data);
    						// removeMessages(MESSAGE_GETCARDLIST);
    						break;
    					case MESSAGE_GETCARDDETAIL:
    						getCardDetail(command.data);
    						break;
    					case MESSAGE_REMOVECARD:
    						removeCard(command.data);
    						break;
    					case MESSAGE_CHECK_BATTERY:
    						checkBattery();
    						break;
    					case MESSAGE_SET_DEFAULT_CARD:
    						setDefaultCard(command.data);
    						break;
    					case MESSAGE_ZAP_CARD:
    						zapCard(command.data);
    						break;
    					case MESSAGE_SET_LOCK_TIME:
    						setLockTimer(command.data);
    					}
    				} else {
    					Message newMsg = sServiceHandler.obtainMessage();
    					newMsg = msg。
    					removeMessages(msg.what);
    					LogHelper.i(LogHelper.CHARGECASE_TAG, newMsg.what + "");
    					sServiceHandler.sendMessageDelayed(newMsg, TIMEDELAY);
    				}
    			} else {
    				Toast.makeText(getApplicationContext(),
    						"Starting ble for you.", Toast.LENGTH_SHORT).show();
    			}
    		}
    	}

    于是我就产生了思考,这样我得newMsg究竟是不是一个新的message呢?

    肯定不是的,不然就没异常了。于是改变写法,让newMsg的what和obj等于原来msg的what和obj,这样做来保持通过handler传递的动作的一致性。和newMsg的崭新性。

    果然,不再报异常了。


    解决方法例如以下:

    private class ChargecaseServiceHandler extends Handler {
    
    		public ChargecaseServiceHandler(Looper looper) {
    			super(looper);
    		}
    
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			Command command = new Command();
    			command.command = msg.what;
    
    			if (msg.obj != null) {
    				command.data = (Bundle) msg.obj;
    			}
    			if (sIsLoopBleServiceReady) {
    				if (isIdle) {
    					switch (msg.what) {
    
    					case MESSAGE_KILL:
    						stopSelf();
    
    						break;
    					case MESSAGE_START_BLE_SCAN:
    						startBLEScan();
    						break;
    					case MESSAGE_CONNECT:
    						connect(command.data);
    						break;
    					case MESSAGE_DISCONNECT:
    						attemptDisconnect();
    						break;
    					case MESSAGE_RELEASE_DEVICE_ID:
    						clearData();
    						break;
    					case MESSAGE_INITIALIZE:
    						initialize();
    						break;
    					case MESSAGE_RESET_BLE:
    						resetBleController();
    						break;
    					case MESSAGE_STARTUP:
    						startup();
    						break;
    					case MESSAGE_REGISTER:
    						register(command.data);
    						break;
    					case MESSAGE_UNREGISTER:
    						unregister(command.data);
    						break;
    					case MESSAGE_RECONNECT:
    						reconnect();
    						break;
    					case MESSAGE_ADDCARD:
    						addCard(command.data);
    						break;
    					case MESSAGE_GETCARDLIST:
    						getCardList(command.data);
    						// removeMessages(MESSAGE_GETCARDLIST);
    						break;
    					case MESSAGE_GETCARDDETAIL:
    						getCardDetail(command.data);
    						break;
    					case MESSAGE_REMOVECARD:
    						removeCard(command.data);
    						break;
    					case MESSAGE_CHECK_BATTERY:
    						checkBattery();
    						break;
    					case MESSAGE_SET_DEFAULT_CARD:
    						setDefaultCard(command.data);
    						break;
    					case MESSAGE_ZAP_CARD:
    						zapCard(command.data);
    						break;
    					case MESSAGE_SET_LOCK_TIME:
    						setLockTimer(command.data);
    					}
    				} else {
    					Message newMsg = sServiceHandler.obtainMessage();
    					newMsg.what = msg.what;
    					newMsg.obj = msg.obj;
    					removeMessages(msg.what);
    					LogHelper.i(LogHelper.CHARGECASE_TAG, newMsg.what + "");
    					sServiceHandler.sendMessageDelayed(newMsg, TIMEDELAY);
    				}
    			} else {
    				Toast.makeText(getApplicationContext(),
    						"Starting ble for you.", Toast.LENGTH_SHORT).show();
    			}
    		}
    	}


    switch的消息非常多。是业务须要,出现的异常也非常经典。特记录之。


    PS:网上非常多解决方法是把new Message()换成obtainMessage(),有的说是把obtainMessage()换成new Message(). 个人亲測无法解决,或是无法解决我的问题。

    PS2: 出现故障和解决这个问题的地方就是在倒数第二个else内。把其它的大段相关代码贴上来的目的是方便自己明确出错情境。请看官勿怪。

    可是我的这样的方法是肯定能够解决类似问题。


  • 相关阅读:
    《数据库系统概论》第三章笔记
    《数据库系统概论》第二章笔记
    《数据库系统概论》第一章笔记
    《Java并发编程的艺术》第九章笔记
    Dijkstra算法
    LaTex插图总结
    PDF中点击参考文献如何回到正文
    清华大学SCI论文写作心得
    LaTex写论文
    MATLAB中ode23函数,龙格库塔函数
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6831302.html
Copyright © 2020-2023  润新知