试图让Android sharedPreference正常工作

问题描述 投票:0回答:2

这是一小段代码,但是我已经对其进行了很多次调整,我不知道它是否仍然明智。我正在尝试将String保存到持久的sharePreference存储中,并在应用启动时获取该字符串。

由于不保存字符串,因此每次尝试输入字符串时代码都会崩溃。

public class MainActivity extends AppCompatActivity {
    TextView displayHours;
    EditText userYears;
    EditText userAge;
    TextView outputText;
    SharedPreferences sharedPref;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        displayHours = (TextView) findViewById(R.id.displayHours);
        userYears = (EditText) findViewById(R.id.userYears);
        userAge = (EditText) findViewById(R.id.userAge);
        outputText = (TextView) findViewById(R.id.outputText);

        sharedPref = getPreferences(Context.MODE_PRIVATE);
        String defaultValue = getString(R.string.user_age);
        String savedAge = sharedPref.getString("AgeData", defaultValue);
        setAgeIfEmpty(savedAge);

        Button calcButton = (Button) findViewById(R.id.calcButton);
        calcButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                float range = 300;

                if (Float.parseFloat(userYears.getText().toString()) <= range) {
                    float years = Float.parseFloat(userYears.getText().toString());
                    float totalHours = years*365*24;
                    String setHours = Float.toString(totalHours);
                    displayHours.setText(setHours);
                }
            }
        });

        EditText ageText = (EditText) findViewById(R.id.userAge);
        ageText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String ageNumber = userAge.getText().toString();
                userAge.setText(ageNumber);

                sharedPref = getPreferences(Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPref.edit();
                editor.putString("AgeData", ageNumber);
                editor.apply();

                Toast myToast = Toast.makeText(getApplicationContext(), "Age Saved!",
                        Toast.LENGTH_SHORT);
                myToast.show();
            }
        });

        ageText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @SuppressLint("StringFormatMatches")
            @Override
            public void afterTextChanged(Editable s) {
                int age = Integer.parseInt(userAge.getText().toString());
                int intYears = Integer.parseInt(userYears.getText().toString());
                String text;

                if (age < intYears/3){
                    text = getString(R.string.Message_1, age);
                    outputText.setText(text);
                }

                else if (intYears < 8 || Integer.parseInt(displayHours.getText().toString()) < 40000){
                    text = getString(R.string.Message_3, displayHours.getText().toString());
                    outputText.setText(text);
                }

                else{
                    text = getString(R.string.Message_2, age);
                    outputText.setText(text);
                }
            }
        });
    }

    public void setAgeIfEmpty(String data) {
        if (!TextUtils.isEmpty(userAge.getText())) {
            userAge.setText(data);
        }
    }

回溯;

    I/zygote:     at void com.android.internal.os.Zygote$MethodAndArgsCaller.run() (Zygote.java:240)
        at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:767)
    D/OpenGLRenderer: HWUI GL Pipeline
    D/: HostConnection::get() New Host Connection established 0xa4ffbf40, tid 7284
    I/OpenGLRenderer: Initialized EGL, version 1.4
    D/OpenGLRenderer: Swap behavior 1
    W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
    D/OpenGLRenderer: Swap behavior 0
    D/EGL_emulation: eglCreateContext: 0x994f6be0: maj 3 min 1 rcv 4
    D/EGL_emulation: eglMakeCurrent: 0x994f6be0: ver 3 1 (tinfo 0x98f23590)
    E/eglCodecCommon: glUtilsParamSize: unknow param 0x000082da
        glUtilsParamSize: unknow param 0x000082da
    I/Choreographer: Skipped 36 frames!  The application may be doing too much work on its main thread.
    D/EGL_emulation: eglMakeCurrent: 0x994f6be0: ver 3 1 (tinfo 0x98f23590)
    W/View: dispatchProvideAutofillStructure(): not laid out, ignoring
    I/AssistStructure: Flattened final assist data: 3872 bytes, containing 1 windows, 14 views
    I/zygote: Background concurrent copying GC freed 3588(934KB) AllocSpace objects, 2(40KB) LOS objects, 67% free, 756KB/2MB, paused 4.816ms total 110.298ms
    I/zygote: Do partial code cache collection, code=20KB, data=29KB
    I/zygote: After code cache collection, code=20KB, data=29KB
        Increasing code cache capacity to 128KB
    I/zygote: Do partial code cache collection, code=49KB, data=51KB
        After code cache collection, code=49KB, data=51KB
        Increasing code cache capacity to 256KB
    D/AndroidRuntime: Shutting down VM
    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.lifewirehours, PID: 7243
        java.lang.NumberFormatException: For input string: ""
            at java.lang.Integer.parseInt(Integer.java:620)
            at java.lang.Integer.parseInt(Integer.java:643)
            at com.example.lifewirehours.MainActivity$3.afterTextChanged(MainActivity.java:98)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:9375)
            at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:11917)
            at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1262)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:574)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:504)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:502)
            at android.text.method.NumberKeyListener.onKeyDown(NumberKeyListener.java:131)
            at android.widget.TextView.doKeyDown(TextView.java:7316)
            at android.widget.TextView.onKeyDown(TextView.java:7093)
            at android.view.KeyEvent.dispatch(KeyEvent.java:2691)
            at android.view.View.dispatchKeyEvent(View.java:11662)
            at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1827)
            at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1827)
            at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1827)
            at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1827)
            at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1827)
            at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1827)
            at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:437)
            at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1818)
            at androidx.core.view.KeyEventDispatcher.activitySuperDispatchKeyEventPre28(KeyEventDispatcher.java:130)
            at androidx.core.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:87)
            at androidx.core.app.ComponentActivity.dispatchKeyEvent(ComponentActivity.java:133)
            at androidx.appcompat.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:558)
            at androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
            at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:2814)
            at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:351)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4714)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4586)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4128)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4181)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4147)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4274)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4155)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4331)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4128)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4181)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4147)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4155)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4128)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6642)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6616)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6577)
            at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3911)
            at android.os.Handler.dispatchMessage(Handler.java:105)
            at android.os.Looper.loop(Looper.java:164)
            at android.app.ActivityThread.main(ActivityThread.java:6541)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
    Process 7243 terminated.


android
2个回答
0
投票

在此行:int age = Integer.parseInt(userAge.getText().toString());之所以会收到NumberFormatException,是因为userAge.getText().toString()返回了一个空字符串(“”),该字符串无法解析为Integer,因为它不是数字。您的日志显示:

java.lang.NumberFormatException: For input string: ""
    at java.lang.Integer.parseInt(Integer.java:620)
    at java.lang.Integer.parseInt(Integer.java:643)
    at com.example.lifewirehours.MainActivity$3.afterTextChanged(MainActivity.java:98)

0
投票

Udi Idan评论和Traendy回答指出了您的错误。您不能将空字符串或非“数字字符串”转换为数字,这将引发NumberFormatException。我认为您应该使用此问题中的函数:

[How can I parse String to int with the default value?

public static int parseWithDefault(String s, int defaultVal) {
    return s.matches("-?\\d+") ? Integer.parseInt(s) : defaultVal;   
}

此功能允许您在转换之前检查输入的字符串,并且如果该字符串不只包含数字,它还允许您使用defaultVal参数指定默认值。

然后您可以更改行

int age = Integer.parseInt(userAge.getText().toString());

收件人

int age = MainActivity.parseWithDefault(userAge.getText().toString(), 100);
© www.soinside.com 2019 - 2024. All rights reserved.