【问题标题】:Trying to get Android sharedPreference to work correctly试图让 Android sharedPreference 正常工作
【发布时间】:2019-11-15 06:51:16
【问题描述】:

这是一小段代码,但我已经调整了很多次,我不知道它是否仍然明智。我正在尝试将字符串保存到持久的 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.


【问题讨论】:

  • 您输入的是什么值?因为这条消息看起来很清楚:java.lang.NumberFormatException: For input string: ""
  • 这是我在这里奇怪解析的 displayText 的条件; ``` else if (intYears
  • 我不确定我是否正确地遵循了您的描述,但setAgeIfEmpty() 中的逻辑似乎不正确。 if (!TextUtils.isEmpty(userAge.getText())) - 也就是说,只有在 userAge 中已经有一些文本时才设置文本。除非您在布局中的 userAge &lt;TextView&gt; 上有带有一些预定义文本的 android:text 属性,否则它不会在那里设置新文本。

标签: android


【解决方案1】:

在这一行: int age = Integer.parseInt(userAge.getText().toString()); 你得到一个 NumberFormatException 因为userAge.getText().toString()返回一个空字符串(“”),因为它不是数字,所以无法解析为整数。 你的日志说:

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)

【讨论】:

  • 谢谢大家,我在这里奇怪地解析了 displayText 的条件; ``` else if (intYears
【解决方案2】:

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);

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 2021-06-29
    • 2017-04-12
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多