You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NetworkChangeListener中无法解析getSupportFragmentManager报错如何解决

问题根因
  • BroadcastReceiver 本身不持有 FragmentManager 实例,getSupportFragmentManager() 是 AppCompatActivity 专属方法,无法在广播接收器中直接调用
  • 新创建的 Messages 实例还未附加到任何宿主,此时调用 getChildFragmentManager() 必然抛出未附加的异常
  • DialogFragment 必须依附于 FragmentActivity(或其子类)/ 已附加的 Fragment 才能展示,不能直接用应用上下文弹出
  • 补充注意:Android 7.0(API 24)及以上系统已经禁用了静态注册的ConnectivityManager.CONNECTIVITY_ACTION广播接收,只能在Activity/Service中动态注册才能收到回调
正确解决方案

首先修正Messages类的构造方式,Android官方要求Fragment必须保留无参构造,否则页面重建时会崩溃,改造为Bundle传参:

public class Messages extends AppCompatDialogFragment {
    private static final String ARG_MESSAGE = "arg_message";

    // 必须保留无参构造
    public Messages() {}

    // 静态工厂方法传参,参数存入Bundle防止重建丢失
    public static Messages newInstance(String message) {
        Messages fragment = new Messages();
        Bundle args = new Bundle();
        args.putString(ARG_MESSAGE, message);
        fragment.setArguments(args);
        return fragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        String message = getArguments() != null ? getArguments().getString(ARG_MESSAGE) : "";
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Warning!!!")
                .setMessage(message)
                .setPositiveButton("ok", null);
        return builder.create();
    }
}

根据你的使用场景二选一即可:

方案1:仅当前活跃页面需要弹窗提示

如果你的NetworkChangeListener是在特定Activity里动态注册的,直接把Activity的FragmentManager传给广播即可:

public class NetworkChangeListener extends BroadcastReceiver {
    private static final String CONNECTION_WIFI_OFF ="WIFI OFF.";
    private FragmentManager fragmentManager;

    // 构造时传入宿主Activity的supportFragmentManager
    public NetworkChangeListener(FragmentManager fragmentManager) {
        this.fragmentManager = fragmentManager;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if(ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())){
            // 先判断状态,避免Activity销毁后弹窗崩溃
            if (!fragmentManager.isStateSaved()) {
                Messages messages = Messages.newInstance(CONNECTION_WIFI_OFF);
                messages.show(fragmentManager,"messages");
            }
        }
    }
}

在注册广播的Activity中初始化即可:

// Activity onCreate内动态注册广播示例
NetworkChangeListener listener = new NetworkChangeListener(getSupportFragmentManager());
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(listener, filter);
// 页面销毁时记得注销广播
@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(listener);
}

方案2:全局任意场景都需要弹窗提示

如果是全局生效的广播,直接弹系统级AlertDialog即可,不需要依赖DialogFragment:

注意:该方案需要申请悬浮窗权限,Android 6.0以上需要动态申请SYSTEM_ALERT_WINDOW权限

@Override
public void onReceive(Context context, Intent intent) {
    if(ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())){
        AlertDialog.Builder builder = new AlertDialog.Builder(context, androidx.appcompat.R.style.Theme_AppCompat_Dialog);
        builder.setTitle("Warning!!!")
                .setMessage(CONNECTION_WIFI_OFF)
                .setPositiveButton("ok", null)
                .setCancelable(true);
        AlertDialog dialog = builder.create();
        // 设置全局弹窗类型
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
        } else {
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        }
        dialog.show();
    }
}

内容的提问来源于stack exchange,提问作者Scripta14

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 04:24:03