即使 Context 发生变化也显示 DialogFragment

Show DialogFragment even when Context changes

我有一个应用程序,其中发送消息并在一段时间后通过 BroadcastReceiver 收到其报告。该报告将通过我正在使用 DialogFragment 的对话框显示给用户,如下所示。

myReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(firstTime)
            firstTime = false; 

        boolean anyError = false;
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            case SmsManager.RESULT_ERROR_NO_SERVICE:
            case SmsManager.RESULT_ERROR_NULL_PDU:
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                anyError = true;
                break;
        }

        sent.add(anyError);
        CustomAlertDialogFragment customAlertDialogFragment = CustomAlertDialogFragment.newInstance("Title",logMessage);
        customAlertDialogFragment.show(getActivity().getSupportFragmentManager(),"TAG");
        sent.clear();
    }
};

CustomDialog 的代码如下。

public class CustomAlertDialogFragment extends DialogFragment {

    public static CustomAlertDialogFragment newInstance(String title, String content) {
        CustomAlertDialogFragment customAlertDialogFragment = new CustomAlertDialogFragment();
        Bundle args = new Bundle();
        args.putString("title",title);
        args.putString("content", content);
        customAlertDialogFragment.setArguments(args);
        return customAlertDialogFragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String title = getArguments().getString("title");
        String content = getArguments().getString("content");
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        // title bar string
        builder.setTitle(title);
        builder.setPositiveButton(R.string.ok, null);

        builder.setMessage(content);
        AlertDialog errorDialog = builder.create();
        // return the Dialog object
        return errorDialog;
    }
}

如果用户同时移动到任何其他 FragmentActivity,则不会显示该对话框。如果它没有获得上下文但它没有,它应该抛出 NullPointerException。可能的替代方案或解决方案是什么。我提到了其他 SO 问题,其中成员要求改用通知,但我的要求是对话。请帮忙。

我猜 Dialogue 正在抛出一个名为 window leaked 的异常。在你的情况下,我认为你可能会考虑使用 Application class。

无论如何,您可以在 Application class 中为您的案例注册 BroadcastReceiver,它将接收广播并按需显示对话。

要检索 Context,您可以使用 getApplicationContext()

public class MyApplication extends Application {

    // Declare the BroadcastReceiver in your Application class
    BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(firstTime)
                firstTime = false; 

            boolean anyError = false;
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                case SmsManager.RESULT_ERROR_NULL_PDU:
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    anyError = true;
                    break;
            }

            sent.add(anyError);
            CustomAlertDialogFragment customAlertDialogFragment = CustomAlertDialogFragment.newInstance("Title",logMessage);
            customAlertDialogFragment.show(getApplicationContext().getSupportFragmentManager(), "TAG");
            sent.clear();
        }
    };

    @Override
    public void onResume() {
        super.onCreate();
        // Register the receiver here 
    }

    @Override
    public void onPause() {
        super.onCreate();
        // Un-register the receiver here 
    }
}

要在您的清单中注册 Application class,您需要定义名称

<application
    android:name="Yourpackage.MyApplication"
    android:allowBackup="false"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:logo="@drawable/your_logo"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:replace="android:icon">

    <!-- Your activities -->
</application>