質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.71%

NullPointerExceptionの原因と解決法を教えてほしいです!

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 194

j06110611

score 12

クイズを作れて保存ができるようにしたいのですが、NullPointerExceptionが出てしまいます。
PreferencesManagerの27行目はspEditor.putString(key.getValue(),s);
MakeQuizActivityの31行目はpm.saveString(strTitle, PreferenceManager.DataKeys.TITLE);
です。
なぜヌルポが出ているのか、解決法をわかりやすく教えていただきたいです。

java.lang.NullPointerException: Attempt to invoke interface method 'android.content.SharedPreferences$Editor android.content.SharedPreferences$Editor.putString(java.lang.String, java.lang.String)' on a null object reference
        at com.test.quizmaker.PreferenceManager.saveString(PreferenceManager.java:27)
        at com.test.quizmaker.MakeQuizActivity$1.onClick(MakeQuizActivity.java:31)
        at android.view.View.performClick(View.java:5610)
        at android.view.View$PerformClick.run(View.java:22265)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
public class MakeQuizActivity extends AppCompatActivity {

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

        Button button2 = (Button)findViewById(R.id.makeQuiz_Button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent2 = new Intent(MakeQuizActivity.this,com.test.quizmaker.MainActivity.class);
                PreferenceManager pm = new PreferenceManager();
                SP(pm.sp, pm.spEditor);
                String strTitle = ((EditText)findViewById(R.id.editText)).getText().toString();
                String strQuiz = ((EditText)findViewById(R.id.editText2)).getText().toString();
                String strAnswer = ((EditText)findViewById(R.id.editText3)).getText().toString();
                pm.saveString(strTitle, PreferenceManager.DataKeys.TITLE);
                startActivity(intent2);
            }
        });
    }
    public void SP(SharedPreferences pmsp, SharedPreferences.Editor pmse){
        pmsp = getSharedPreferences("DataStore", MODE_PRIVATE);
        pmse = pmsp.edit();
    }
}
public class PreferenceManager{

    public SharedPreferences sp;
    public SharedPreferences.Editor spEditor;

    public enum DataKeys {
        TITLE("title"), QUIZ("quiz"), ANSWER("answer");

        private String value;

        private DataKeys(String value) {
            this.value = value;
        }
        public String getValue() {
            return this.value;
        }
    }

    public void saveString(String s, DataKeys key){
        spEditor.putString(key.getValue(),s);
        spEditor.apply();
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • gentaro

    2019/08/10 14:08

    デバッグの丸投げ依頼では

    キャンセル

  • m.ts10806

    2019/08/10 14:11

    原因も解決法方もほぼほぼ出尽くしてる内容と思いますが。原因はエラーの通りですしね

    キャンセル

  • s.m_1

    2019/08/10 17:28

    たしかに、gentaro さん、m.ts10806 さんのおっしゃる通りだと思います。
    ただ、そのような質問が多いということも事実ですよね。

    キャンセル

回答 2

checkベストアンサー

0

java.lang.NullPointerException: Attempt to invoke interface method 'android.content.SharedPreferences$Editor android.content.SharedPreferences$Editor.putString(java.lang.String, java.lang.String)' on a null object reference


このエラーが伝えてくれていることは、

SharedPreferences.Editor は存在しなから参照 (使うことが) できないよ !

ということです。

つまり、

public SharedPreferences sp;
public SharedPreferences.Editor spEditor;


この 2 つのオブジェクトは初期化できていないということです。

なので、

SP(pm.sp, pm.spEditor);


の代わりに、

public void init(SharedPreferences sp, SharedPreferences.Editor editor) {
  this.sp = sp;
  this.spEditor = editor;
}

を追加して、

Intent intent2 = new Intent(MakeQuizActivity.this,com.test.quizmaker.MainActivity.class);
PreferenceManager pm = new PreferenceManager();
// ここを追加しました。
SharedPreferences sp = getSharedPreferences("DataStore", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
pm.init(sp, editor);
// SP(pm.sp, pm.spEditor);
String strTitle = ((EditText)findViewById(R.id.editText)).getText().toString();
String strQuiz = ((EditText)findViewById(R.id.editText2)).getText().toString();
String strAnswer = ((EditText)findViewById(R.id.editText3)).getText().toString();
pm.saveString(strTitle, PreferenceManager.DataKeys.TITLE);
startActivity(intent2);

onClickメソッドの中を上のように変えると、正常に動くと思います。

基本的に、ヌルポは参照先のオブジェクトが初期化されていない場合に起こることが多いので、今回のような時は、オブジェクトがnullかどうかをLog.dなどで確認したほうが良いと思います。

以上、参考になれば幸いです。

追記ですが、PreferenceManagerのコンストラクタにContextを渡すことで、PreferenceManagerが初期化された際に、 SharedPreferencesSharedPreferences.Editorを初期化することができます。(俗に言うコンストラクタイジェクションです)

では、長文失礼いたしました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

そもそも、nullのものにアクセスしている、という例外です
だもんで、エラーが出たという行に登場している変数、クラス、メソッドの内容を手当たり次第にチェックしてみましょう
そのなかにnullのものを見つけたら、なぜそうなのか、これを解消するためには何をすればいいか、を考えましょう

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.71%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る