Unable to stop activity {com.xxx.xxx.Activity}: java.lang.IllegalArgumentException: Receiver not registered: com.xx.xxx.fragment$1@8a6d2bc
public class BaseFragment extends Fragment {
public IntentFilter filter = new IntentFilter();
private BroadcastReceiver mDateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
onReceiveProcess(intent);
}
};
/**
* 处理广播事件
*/
protected void onReceiveProcess(Intent intent) {
}
protected void registerSysReceiver() {
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getBaseActivity().registerReceiver(mDateReceiver, filter);
}
protected void unregisterSysReceiver() {
getBaseActivity().unregisterReceiver(mDateReceiver);
}
@Override
public void onStart() {
super.onStart();
if (!isHidden()) {
registerSysReceiver();
}
}
@Override
public void onStop(){
super.onStop();
unregisterSysReceiver();
}
}
public class ActivityV extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
displayFragment(new BaseFragment(),R.id.container);
}
@Override
public void displayFragment(BaseFragment targetFrg, int containerId) {
if (targetFrg == null) {
return;
}
FragmentTransaction transaction = mActivity.getSupportFragmentManager().beginTransaction();
try {
transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
if (targetFrg.isAdded()) {
transaction.hide(mCurrentFrg);
transaction.show(targetFrg);
} else {
if (mCurrentFrg != null) {
transaction.hide(mCurrentFrg);
}
if (mFragments.contains(targetFrg)) {
transaction.show(targetFrg);
} else {
transaction.add(containerId, targetFrg, targetFrg.getClass().getName());
mFragments.add(targetFrg);
}
}
mCurrentFrg = targetFrg;
transaction.commitAllowingStateLoss();
} catch (Exception e) {
e.printStackTrace();
}
}
}
基本流程代码是这样的,看起来可能是很正常的系统广播注册与反注册流程,但为什么偏偏会在OnStop的时候进行反注册,报了如下的错呢?
2023-11-17 15:18:45.454 13985-13985/kdv.mt.mtui.skywalker E/AndroidRuntime: FATAL EXCEPTION: main
Process: kdv.mt.mtui.skywalker, PID: 13985
java.lang.RuntimeException: Unable to stop activity {xx.xx.xx.xx/xx.xxx.xx.xx.xx.xx.xxxxActivityV}: java.lang.IllegalArgumentException: Receiver not registered: xx.xx.xx.xx.xx.xx.BaseFragment$1@5d7b1ae
at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4151)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:4121)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:4196)
at android.app.servertransaction.StopActivityItem.execute(StopActivityItem.java:41)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: Receiver not registered: xxxx.xx.xx.xx.xx.xxx.BaseFragment$1@5d7b1ae
at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:1271)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1504)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:659)
at xxx.xxx.xxx.xxx.xx.xxx.xxxx.onStop(BaseFragment.java:134)
at androidx.fragment.app.Fragment.performStop(Fragment.java:2797)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:940)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
at androidx.fragment.app.FragmentManagerImpl.dispatchStop(FragmentManagerImpl.java:2634)
at androidx.fragment.app.FragmentController.dispatchStop(FragmentController.java:290)
at androidx.fragment.app.FragmentActivity.onStop(FragmentActivity.java:564)
at xxx.xx.xx.xx.xxx.xxx.BaseActivity.onStop(BaseActivity.java:648)
at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1432)
at android.app.Activity.performStop(Activity.java:7367)
at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4143)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:4121)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:4196)
at android.app.servertransaction.StopActivityItem.execute(StopActivityItem.java:41)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
简答总结一下上面的操作:
在一个fragmentA里面onstart && !isHidden()的时候注册一个系统广播CONNECTIVITY_ACTION,然后再onstop的时候进行反注册;然后在fragmentA中open一个新的Activity,此时会在fragmentA的onstop的反注册时机上,导致apk崩溃;
我尝试怀疑过
1、注册广播使用的Context不对;改用成更高层的applicationContext问题依旧
2、反注册时机,延后到ondestory或者往前onpause,甚至在onhiddenchange回调里面去做反注册,问题都是一样的相似
最终大家了打印,在fragment的OnStart注册之前把Context和BroadcastReceiver两个对象打出来,反注册时也把这两个对象打出来。发现两点原因:
原因
1、Context前后不一致了;注册和反注册使用到的Context不是同一个;
2、BroadcastReceiver对象前后不一致;注册时用到的广播器对象和反注册用到的广播器对象不是同一个;
这是我犯的错;
潜在的原因其实还有可能是
3、你的系统广播没有注册成功
4、反注册的时机不对;