Приложение выдает сбой после сохранения значения в общих настройках - PullRequest
0 голосов
/ 21 июня 2020

Я пытаюсь запрограммировать свое первое приложение с помощью Android Studio (с java) и застрял. Приложение должно принимать ввод от пользователя (с помощью обычного текста), а затем сохранять его и отображать при следующем запуске приложения. Я хочу иметь возможность хранить данные между запусками приложения, и, насколько я понял, наиболее эффективным и элегантным способом является использование общих настроек. Но каждый раз, когда я нажимаю кнопку, сохраняющую текст в общих настройках, приложение вылетает.

Это мой код:

public class FirstFragment extends Fragment {
    
    private final String PREFS = "sharedPrefs";
    private final String INPUT = "user_input";
    private final String MEMO = "memo";
    SharedPreferences sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false);
    }

    private void saveData(View view) {
        TextView input = view.findViewById(R.id.user_input);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(MEMO, input.getText().toString());
        editor.apply();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

        TextView memos = view.findViewById(R.id.memos);
        memos.setText(sharedPreferences.getString(MEMO, ""));

        view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                saveData(view);
            }
        });
    }

EDIT: my cra sh logs:

Process: com.example.myfirstapplication, PID: 2322
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference
        at com.example.myfirstapplication.FirstFragment.saveData(FirstFragment.java:32)
        at com.example.myfirstapplication.FirstFragment.access$000(FirstFragment.java:14)
        at com.example.myfirstapplication.FirstFragment$1.onClick(FirstFragment.java:47)
        at android.view.View.performClick(View.java:7161)
        at android.view.View.performClickInternal(View.java:7138)
        at android.view.View.access$3500(View.java:811)
        at android.view.View$PerformClick.run(View.java:27419)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7520)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

Был бы рад узнать, есть ли у кого-нибудь решение моей проблемы!

Ответы [ 3 ]

1 голос
/ 21 июня 2020

Добавление назначения вашего объекта SharedPrefrence как поля Fragment обязательно вызовет исключение, потому что оно вызывается до того, как фрагмент будет присоединен к вашей активности, и с точки зрения жизненного цикла фрагмента , обратный вызов onAttach() еще не вызван, поэтому getActivity() будет нулевым.

SharedPreferences sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

И исключение, которое вы получите, будет примерно таким:

java.lang.IllegalStateException: Fragment FirstFragment{cfb327} (a42392bd-ee02-48a2-9d61-aaa8c455bb10)} not attached to an activity.

Чтобы решить эту проблему, замените строку ниже

SharedPreferences sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

на

SharedPreferences sharedPreferences;

И вы уже инициализировали его в методе onViewCreated().

1 голос
/ 21 июня 2020

когда вы нажимаете кнопку, вы вызываете метод saveData (). но вы устанавливаете вид кнопки в качестве аргумента, а не root view. вы должны сделать вот так

view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) { 
        // change onClick's parameter name from view to v
            saveData(view);
        }
    });
0 голосов
/ 22 июня 2020

Используя отладчик, вы можете увидеть, что в функции saveData переменная input остается Null. Чтобы решить эту проблему, замените:

TextView input = view.findViewById(R.id.user_input);

на:

TextView input = getActivity().findViewById(R.id.user_input);

Вы можете проверить значение input, чтобы убедиться, что нужная строка действительно существует.

ps Теперь использование параметра view в вашей функции является избыточным и должно быть удалено.

...