首页 > 解决方案 > 在 DialogFragment 中更改布局时出现 IllegalStateException

问题描述

当我进行一些布局更改时,我的 DialogFragment 中的某些设备上会出现 IllegalStateExceptions。在我的 DialogFragment 中,我通过 Volley 从 JSON 获取一些数据,当发生 ResponseError 时,我想更改一些视图。因此,例如,这是我的视图更改方法:

private void showErrorLayout() {
        mProgressBar.setVisibility(View.INVISIBLE);
        mText.setVisibility(View.VISIBLE);
        mText.setText(getString(R.string.volley_firmware_update_error));
}

这是我的 Volley 方法:

private void checkVersionNetwork() {
    final int fw = sharedPreferencesManager.loadFirmwareVersion();
        JsonObjectRequest request = new JsonObjectRequest(
                Request.Method.GET, JSON_LINK, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject object = response.getJSONObject(OBJECT);
                    JSONObject changelogObject = response.getJSONObject(CHANGELOG_OBJECT);

                    if (fw >= Integer.parseInt(object.getString(JSON_FIRMWARE_VERSION))) {
                        Log.i(LOG_TAG, "onResponse: FIRMWARE IS UP TO DATE");
                        mText.setText(R.string.firmware_most_recent);
                        mButton.setText(R.string.sb_ok);
                        btnClose.setVisibility(View.INVISIBLE);
                        mText.setVisibility(View.VISIBLE);
                        mButton.setVisibility(View.VISIBLE);
                        mProgressBar.setVisibility(View.INVISIBLE);

                    } else {
                        Log.i(LOG_TAG, "onResponse: FIRMWARE IS OUT OF DATE");

                        if (Locale.getDefault().getLanguage().equals("en")) {
                            mText.setText(getString(R.string.firmware_need_download) + "\n" + getString(R.string.changes) + "\n" + changelogObject.getString(JSON_FIRMWARE_CHANGELOG_TEXT_ENG));
                        } else if (Locale.getDefault().getLanguage().equals("de")) {
                            mText.setText(getString(R.string.firmware_need_download) + "\n" + getString(R.string.changes) + "\n"  + changelogObject.getString(JSON_FIRMWARE_CHANGELOG_TEXT_GER));
                        }
                        mText.setVisibility(View.VISIBLE);
                        mButton.setVisibility(View.VISIBLE);
                        mProgressBar.setVisibility(View.INVISIBLE);
                        downloadLink = object.getString("url");
                        Log.i(LOG_TAG, "onResponse: " + downloadLink);
                        mButton.setText(getContext().getResources().getString(R.string.download));
                    }
                    Log.i("RESPONSE", object.getString(JSON_FIRMWARE_VERSION));
                } catch (JSONException | NullPointerException e) {
                    e.printStackTrace();
                    showErrorLayout();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("VOLLEY", error.toString());
                showErrorLayout();
            }
        }
        );

        mRequestQueue.add(request);
    //}
}

来自带有 Android 8.0 的三星 Galaxy S7 的错误消息:

java.lang.IllegalStateException: 
  at android.support.v4.app.Fragment.requireContext (Fragment.java:614)
  at android.support.v4.app.Fragment.getResources (Fragment.java:678)
  at android.support.v4.app.Fragment.getString (Fragment.java:700)
  at de.app.haveltec.ilockit.fragment.dialogfragment.FirmwareUpdateDialogFragment.showErrorLayout (FirmwareUpdateDialogFragment.java:172)
  at de.app.haveltec.ilockit.fragment.dialogfragment.FirmwareUpdateDialogFragment.access$1000 (FirmwareUpdateDialogFragment.java:51)
  at de.app.haveltec.ilockit.fragment.dialogfragment.FirmwareUpdateDialogFragment$6.onErrorResponse (FirmwareUpdateDialogFragment.java:269)
  at com.android.volley.Request.deliverError (Request.java:630)
  at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run (ExecutorDelivery.java:108)
  at android.os.Handler.handleCallback (Handler.java:789)
  at android.os.Handler.dispatchMessage (Handler.java:98)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6944)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

标签: android

解决方案


HTTP 请求在完成时调用 onResponse() 或 onError()(在主线程上工作),而不知道 Activity 是否仍在前台。如果 Activity 消失(用户导航到别处), getActivity() 返回 null 并检查是否添加了 DialogFragment。

此行有错误,请试试这个

if(getActivity()!=null && isAdded()) {
    mText.setText(getActivity().getResources().getString(R.string.volley_firmware_update_error));
}

推荐阅读