【已解决】BroadcastReceiver的onReceive执行完毕后返回结果出错:LoadedApk$ReceiverDispatcher$Args.run

【问题】

如下代码:

 private final BroadcastReceiver mBtModuleStatusChangeReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
         final String action = intent.getAction(); 
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 
            int btCurState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 
            int btPrevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR); 
            //int btCurState = intent.getParcelableExtra(BluetoothAdapter.EXTRA_STATE); 
            //int btPrevState = intent.getParcelableExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE); 
            CommunicationState prevCommState = btStateToCommState(btPrevState); 
            CommunicationState curCommState = btStateToCommState(btCurState); 
            if((CommunicationState.UNKNOWN != prevCommState) && (CommunicationState.UNKNOWN != curCommState)){ 
                //only notify when enable/disable blutooth module 
                ModuleStatusPara moduleStatePara = new ModuleStatusPara(); 
                moduleStatePara.setCommType(CommunicationType.BLUETOOTH); 
                moduleStatePara.setPrevState(prevCommState); //ENABLED 
                moduleStatePara.setCurState(curCommState); //DISABLING 
                if(null != mModuleStateChanged){ 
                    mModuleStateChanged.Execute(this, moduleStatePara, null); 
                } 
            } 
         } 
     } 
 };

在执行完毕后,返回时,挂掉了,如图:

BroadcastReceiver onReceive return

LoadedApk ReceiverDispatcher Args.run source not found

 

【折腾过程】

1.折腾了半天,最终结果是:

对于同一个ACTION,多次注册了同一个intentFilter,而导致会挂掉。

去掉后来的第二次的注册,即可。

即,本来通过:

 private final BroadcastReceiver mBtModuleStatusChangeReceiver = new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
         final String action = intent.getAction();
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
             int btCurState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
             int btPrevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
          //int btCurState = intent.getParcelableExtra(BluetoothAdapter.EXTRA_STATE);
          //int btPrevState = intent.getParcelableExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE);
          CommunicationState prevCommState = btStateToCommState(btPrevState);
          CommunicationState curCommState = btStateToCommState(btCurState);
             if((CommunicationState.UNKNOWN != prevCommState) && (CommunicationState.UNKNOWN != curCommState)){
              //only notify when enable/disable blutooth module
           ModuleStatusPara moduleStatePara = new ModuleStatusPara();
           moduleStatePara.setCommType(CommunicationType.BLUETOOTH);
           moduleStatePara.setPrevState(prevCommState); //ENABLED
           moduleStatePara.setCurState(curCommState); //DISABLING
           if(null != mModuleStateChanged){
            mModuleStateChanged.Execute(this, moduleStatePara, null);
           }
             }
         }
     }
 };
 
     private void listenBluetoothModuleStateChange(){
        // Register for broadcasts on BluetoothAdapter state change 
        IntentFilter btStateChangeFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        AppContext.getInstance().getAppContext().registerReceiver(mBtModuleStatusChangeReceiver, btStateChangeFilter);
    }

已经对于BluetoothAdapter.ACTION_STATE_CHANGED注册过了。

但是后来又再次注册了一遍(虽然用的不是同一个IntentFilter):

 private final BroadcastReceiver mBtAdapterStatusChangeReceiver = new BroadcastReceiver() {
     @Override
     public void onReceive(Context context, Intent intent) {
         final String action = intent.getAction();
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
             int btCurState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
             int btPrevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
             BluetoothDevice curBtDev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             String btDevMacAddr = curBtDev.getAddress();
             AdapterState prevAdapterState = btStateToAdapterState(btPrevState);
             AdapterState curAdapterState = btStateToAdapterState(btCurState);
             
             if((AdapterState.UNKNOWN != prevAdapterState) && (AdapterState.UNKNOWN != curAdapterState)){
              //only notify when blutooth adapter connect/disconnect
           AdapterStatePara adapterStatePara = new AdapterStatePara();
           adapterStatePara.setCommType(CommunicationType.BLUETOOTH);
           adapterStatePara.setAdapterId(btDevMacAddr);
           adapterStatePara.setPrevState(prevAdapterState);
           adapterStatePara.setCurState(curAdapterState);
           if(null != mAdapterStateChanged){
            mAdapterStateChanged.Execute(this, adapterStatePara, null);
           }
             }
         }
     }
 };

           // Register for broadcasts on BluetoothAdapter state change
           IntentFilter btAdapterStateChangeFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
           AppContext.getInstance().getAppContext().registerReceiver(mBtAdapterStatusChangeReceiver, btAdapterStateChangeFilter);

然后导致会挂掉。

解决办法是:

去掉后面的第二次的注册,只用单个的IntentFilter去处理BluetoothAdapter.ACTION_STATE_CHANGED就可以了:

	private final BroadcastReceiver mBtModuleStatusChangeReceiver = new BroadcastReceiver() {
	    @Override
	    public void onReceive(Context context, Intent intent) {
	        final String action = intent.getAction();
	        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
	            int btCurState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
	            int btPrevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);

	            if(null != mModuleStateChanged){
		        	//int btCurState = intent.getParcelableExtra(BluetoothAdapter.EXTRA_STATE);
		        	//int btPrevState = intent.getParcelableExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE);
		            
		        	CommunicationState prevCommState = btStateToCommState(btPrevState);
		        	CommunicationState curCommState = btStateToCommState(btCurState);
		            if((CommunicationState.UNKNOWN != prevCommState) && (CommunicationState.UNKNOWN != curCommState)){
			        	//only notify when enable/disable blutooth module
			        	ModuleStatusPara moduleStatePara = new  ModuleStatusPara();
			        	moduleStatePara.setCommType(CommunicationType.BLUETOOTH);
			        	moduleStatePara.setPrevState(prevCommState); //ENABLED
			        	moduleStatePara.setCurState(curCommState); //DISABLING

		        		mModuleStateChanged.Execute(this, moduleStatePara, null);
		        	}
	            }

	        	if(null != mAdapterStateChanged){
		            BluetoothDevice curBtDev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
		            String btDevMacAddr = curBtDev.getAddress();

		            AdapterState prevAdapterState = btStateToAdapterState(btPrevState);
		            AdapterState curAdapterState = btStateToAdapterState(btCurState);
		            if((AdapterState.UNKNOWN != prevAdapterState) && (AdapterState.UNKNOWN != curAdapterState)){
		            	//only notify when blutooth adapter connect/disconnect
			        	AdapterStatePara adapterStatePara = new  AdapterStatePara();
			        	adapterStatePara.setCommType(CommunicationType.BLUETOOTH);
			        	adapterStatePara.setAdapterId(btDevMacAddr);
			        	adapterStatePara.setPrevState(prevAdapterState);
			        	adapterStatePara.setCurState(curAdapterState);
			        	
			            mAdapterStateChanged.Execute(this, adapterStatePara, null);
		            }
	        	}
	        }
	    }
	};
    
    private void listenBluetoothModuleStateChange(){
        // Register for broadcasts on BluetoothAdapter state change
        IntentFilter btStateChangeFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        AppContext.getInstance().getAppContext().registerReceiver(mBtModuleStatusChangeReceiver, btStateChangeFilter);
    }

 

【总结】

貌似对于同一个ACTION,比如BluetoothAdapter.ACTION_STATE_CHANGED

是不能多次注册的,否则会挂掉的。



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量