首页 > 解决方案 > Android:来自 Google Play 控制台的 java.lang.IllegalStateException

问题描述

有时,我的应用程序(来自 Google Play 控制台)中会出现异常:

java.lang.IllegalStateException: 

  at android.support.v4.app.Fragment.requireContext (Fragment.java:696)

  at android.support.v4.app.Fragment.getResources (Fragment.java:760)

  at com.my_domain.mu_app.TravelCostFragment$MyTextWatcherListener.onTextChanged (TravelCostFragment.java:195)

  at android.widget.TextView.sendOnTextChanged (TextView.java:10099)

  at android.widget.TextView.setText (TextView.java:5921)

  at android.widget.TextView.setText (TextView.java:5759)

  at android.widget.EditText.setText (EditText.java:122)

  at android.widget.TextView.setText (TextView.java:5716)

  at com.my_domain.mu_app.TravelCostFragment.updateLabelsUI (TravelCostFragment.java:119)

  at com.my_domain.mu_app.TravelCostFragment.onSettingDialogDissmised (TravelCostFragment.java:173)

  at com.my_domain.mu_app.MainActivity.onResultDialogClosed (MainActivity.java:182)

  at com.my_domain.mu_app.BaseDialogFragment.onDismiss (BaseDialogFragment.java:135)

  at android.app.Dialog$ListenersHandler.handleMessage (Dialog.java:1547)

  at android.os.Handler.dispatchMessage (Handler.java:109)

  at android.os.Looper.loop (Looper.java:207)

  at android.app.ActivityThread.main (ActivityThread.java:7539)

  at java.lang.reflect.Method.invoke (Native Method)

  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:524)

  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:958)

我认为当用户关闭对话框或更改设备上的语言时会出现问题。但是,我无法在 Android Studio Emulator 中重现此问题。

这是 TravelCostFragment 的代码:

package com.my_domain.mu_app;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.my_domain.mu_app.interfaces.OnMainActivityListener;
import com.my_domain.mu_app.utilities.Helper;
import com.my_domain.mu_app.utilities.SharedPref;

import java.util.HashMap;

public class TravelCostFragment extends BaseFragment implements OnMainActivityListener {

    private static String TAG = TravelCostFragment.class.getSimpleName();

    public static final int TAB_POSITION = 0;

    private TextView mLabelAverageFuelConsumption;
    private TextView mLabelDistanceUnit;
    private TextView mLabelPrice;
    private TextView mLabelPersons;
    private EditText mValueAverageFuelConsumption;
    private EditText mValueDistanceUnit;
    private EditText mValuePrice;
    private EditText mValuePersons;
    private LinearLayout mPersonsSection;
    private Button mCalculateButton;
    private View mSpace2;

    public TravelCostFragment() {}

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.fragment_travel_cost, container, false);

        // Init widgets
        mLabelAverageFuelConsumption = (TextView) layout.findViewById(R.id.labelAverageFuelConsumption);
        mLabelDistanceUnit           = (TextView) layout.findViewById(R.id.labelDistanceUnit);
        mLabelPrice                  = (TextView) layout.findViewById(R.id.labelPrice);
        mLabelPersons                = (TextView) layout.findViewById(R.id.labelPersons);
        mValueAverageFuelConsumption = (EditText) layout.findViewById(R.id.valueAverageFuelConsumption);
        mValueDistanceUnit           = (EditText) layout.findViewById(R.id.valueDistanceUnit);
        mValuePrice                  = (EditText) layout.findViewById(R.id.valuePrice);
        mValuePersons                = (EditText) layout.findViewById(R.id.valuePersons);
        mPersonsSection              = (LinearLayout) layout.findViewById(R.id.personsSection);
        mCalculateButton             = (Button) layout.findViewById(R.id.calculateButton);
        mSpace2                      = (View) layout.findViewById(R.id.space2);

        Helper.fineTuningText(mLabelAverageFuelConsumption);
        Helper.fineTuningText(mLabelDistanceUnit);
        Helper.fineTuningText(mLabelPrice);
        Helper.fineTuningText(mLabelPersons);

        // Prepare widgets
        mValueAverageFuelConsumption.addTextChangedListener(new MyTextWatcherListener(mValueAverageFuelConsumption));
        mValueDistanceUnit.addTextChangedListener(new MyTextWatcherListener(mValueDistanceUnit));
        mValuePrice.addTextChangedListener(new MyTextWatcherListener(mValuePrice));
        mValuePrice.setImeOptions(EditorInfo.IME_ACTION_DONE);
        mValuePersons.addTextChangedListener(new MyTextWatcherListener(mValuePersons));
        mCalculateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HashMap<String, String> data = new HashMap<String, String>();
                data.put(BaseDialogFragment.KEY_AVERAGE_FUEL, mValueAverageFuelConsumption.getText().toString());
                data.put(BaseDialogFragment.KEY_DISTANCE, mValueDistanceUnit.getText().toString());
                data.put(BaseDialogFragment.KEY_PRICE, mValuePrice.getText().toString());
                data.put(BaseDialogFragment.KEY_PERSONS, mValuePersons.getText().toString());

                SharedPref.getInstance(mContext).setAverageFuelConsumption(mValueAverageFuelConsumption.getText().toString());

                FragmentTransaction ft = getFragmentManager().beginTransaction();
                Fragment prev = getFragmentManager().findFragmentByTag(TravelCalculationDialog.TRAVEL_CALCULATION_DIALOG);
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);

                DialogFragment dialog = TravelCalculationDialog.newInstance(data);
                dialog.show(ft, TravelCalculationDialog.TRAVEL_CALCULATION_DIALOG);
            }
        });

        // DEBUG data
        /*mValueAverageFuelConsumption.setText("8");
        mValueDistanceUnit.setText("320");
        mValuePrice.setText("2.39");
        mValuePersons.setText("4");*/

        updateLabelsUI();

        return layout;
    }

    // ---------------------------------------------------------------------------------------------
    // Auxiliary methods
    // ---------------------------------------------------------------------------------------------

    private void updateLabelsUI() {
        try {
            mLabelAverageFuelConsumption.setText(Helper.get(mContext).getAverageFuelLabel());
            mLabelDistanceUnit.setText(Helper.get(mContext).getDistanceLabel());
            mLabelPrice.setText(Helper.get(mContext).getPriceLabel());

            String averFuelCons = SharedPref.getInstance(mContext).getAverageFuelConsumption();
            if (averFuelCons != null && !averFuelCons.isEmpty()) {
                mValueAverageFuelConsumption.setText(SharedPref.getInstance(mContext).getAverageFuelConsumption());
            }
            mValueAverageFuelConsumption.setHint(Helper.get(mContext).getAverageFuelHint());
        } catch (NullPointerException e) {

        }
    }

    private void visibilityPeopleLinearLayout() {
        double price = 0d;

        String valuePrice = mValuePrice.getText().toString();

        if (!valuePrice.isEmpty()) {
            try {
                price = Double.parseDouble(valuePrice);
            } catch(NumberFormatException e) {}
        }

        if (price > 0) {
            mSpace2.setVisibility(View.VISIBLE);
            mPersonsSection.setVisibility(View.VISIBLE);
        } else {
            mSpace2.setVisibility(View.GONE);
            mPersonsSection.setVisibility(View.GONE);
        }
    }

    private void visibilityCalculateButton() {
        double averageFuel = 0d, distance = 0d;

        String valueAverageFuel = mValueAverageFuelConsumption.getText().toString();
        String valueDistance = mValueDistanceUnit.getText().toString();

        if (!valueAverageFuel.isEmpty()) {
            try {
                averageFuel = Double.parseDouble(valueAverageFuel);
            } catch(NumberFormatException e) {}
        }
        if (!valueDistance.isEmpty()) {
            try {
                distance = Double.parseDouble(valueDistance);
            } catch(NumberFormatException e) {}
        }

        if (averageFuel > 0 && distance > 0) {
            mCalculateButton.setEnabled(true);
        } else {
            mCalculateButton.setEnabled(false);
        }
    }

    @Override
    public void onSettingDialogDissmised() {
        updateLabelsUI();
    }

    // ---------------------------------------------------------------------------------------------
    // Auxiliary inner classes
    // ---------------------------------------------------------------------------------------------

    private class MyTextWatcherListener implements TextWatcher {

        private EditText mEdit;

        public MyTextWatcherListener(EditText edit) {
            mEdit = edit;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (getResourceName().equals( getResources().getResourceName(R.id.valuePrice) )) {
                visibilityPeopleLinearLayout();
            } else {
                visibilityCalculateButton();
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }

        private String getResourceName() {
            return mEdit.getResources().getResourceName(mEdit.getId());
        }
    }

}

请帮助解决这个问题。

标签: androiduser-interface

解决方案


这是因为在您脱离活动MyTextWatcherListener后仍会触发您。TravelCostFragment当您的片段被销毁时,您可以尝试从编辑文本中删除侦听器

MyTextWatcherListener averageFuelConsumptionWatcher = null;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    averageFuelConsumptionWatcher = new MyTextWatcherListener(mValueAverageFuelConsumption)
 mValueAverageFuelConsumption.addTextChangedListener(averageFuelConsumptionWatcher);
}
@Override
public void onDestroyView() {
        averageFuelConsumptionWatcher = null;
        super.onDetach();
}

推荐阅读