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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

3回答

5564閲覧

Androidアプリ(Java)でプリファレンスにデータを保存したい

Hiso0802

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2016/07/25 01:03

編集2016/07/25 02:56

###AndroidアプリをJavaで作成しています。プリファレンスについて質問です。
はじめまして。
半年前からJavaを習い始め、Androidアプリ開発は1ヶ月未満の初心者です。
RPGのようなアプリを作成しており、アプリ内にデータを保持するのにプリファレンスというものがあるのを知って実装したいと思っております。
しかし、プリファレンスに関してはネットで調べた知識しかなく、コードをどう書いたら実装できるのか、何故うまくいかないのか分かりません。

主人公キャラを男性か女性かラジオボタンで選択 → ダイアログが出る → 進むとプリファレンスに主人公の初期データを登録
という流れにしたいと思っています。

###該当ソースコード
「First.java」(最初に起動されるもの。ラジオボタンやダイアログが出る)
「chara_pref.java」(キャラクターのデータをプリファレンスに登録)
「PrefAct.java」(PreferenceActivityで何かする必要があるとネットで見て作ったもの)と、
「ch_main.xml」(データを登録したいXML)
の4つを掲載します。

●First.java(全文)
クラスについて…
First extends Activity : 主にViewをセットしている。画面表示用
ChooseMain implements View.OnClickListener : ダイアログのカスタムレイアウトを呼び出している
DialogFragBoy extends DialogFragment : 「男の子」を選んだ際に出るダイアログの設定
DialogFragGirl extends DialogFragment : 「女の子」を選んだ際に出るダイアログの設定
「First」で「setOnClickListener(new ChooseMain())」を呼んでいます。
時数の関係で割愛しています

class ChooseMain implements View.OnClickListener { public void onClick(View v) { RadioButton rb = (RadioButton) v; if(rb == boy) { System.out.println("男の子ダイアログ生成 : First"); manage = getFragmentManager(); frag = new DialogFragBoy(); frag.show(manage, "Choose Main"); } else if(rb == girl) { System.out.println("女の子ダイアログ生成 : First"); manage = getFragmentManager(); frag = new DialogFragGirl(); frag.show(manage, "Choose Main"); } } } public static class DialogFragBoy extends DialogFragment { private AlertDialog dialogBoy ; private AlertDialog.Builder alert; chara_pref cp; public Dialog onCreateDialog(final Bundle savedInstanceState) { alert = new AlertDialog.Builder(getActivity()); // カスタムレイアウトの生成 View alertView = getActivity().getLayoutInflater().inflate(R.layout.dialogboy, null ); Button b = (Button) alertView.findViewById(R.id.button); b.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { System.out.println("男の子クリック : First"); cp = new chara_pref(); cp.chara_main("boy"); } }); alert.setView(alertView); dialogBoy = alert.create(); dialogBoy.show(); return dialogBoy; } } public static class DialogFragGirl extends DialogFragment { private AlertDialog dialogGirl ; private AlertDialog.Builder alert; chara_pref cp; public Dialog onCreateDialog(Bundle savedInstanceState) { alert = new AlertDialog.Builder(getActivity()); // カスタムレイアウトの生成 View alertView = getActivity().getLayoutInflater().inflate(R.layout.dialoggirl, null ); Button b = (Button) alertView.findViewById(R.id.button); b.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { System.out.println("女の子クリック : First"); cp = new chara_pref(); cp.chara_main("girl"); // Intent inte = new Intent(chara_pref.class); } }); alert.setView(alertView); dialogGirl = alert.create(); dialogGirl.show(); return dialogGirl; } } }

●「chara_pref.java」(修正依頼をいただき、全文掲載しました)

package hiso.rpg; //import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; //import android.os.PersistableBundle; import android.preference.PreferenceActivity; //import android.preference.PreferenceFragment; import android.preference.PreferenceManager; public class chara_pref extends PreferenceActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public void chara_main(String s) { System.out.println("主人公プリファレンス登録メソッド : chara_pref"); // SharedPreferences pref = getSharedPreferences("ch_main", MODE_PRIVATE); // PreferenceFragment pf = new PrefFrag(); // startPreferenceFragment(pf, false); startActivity(new Intent(this, PrefAct.class)); SharedPreferences ch_main = PreferenceManager.getDefaultSharedPreferences(this); ed.putString("main_sx", main_sx); ed.putInt("main_hairstyle", main_hs); ed.putInt("main_haircolor", main_hc); ed.putInt("main_eyestyle", main_es); ed.putInt("main_eyecolor", main_ec); ed.putInt("main_job", main_job); // 攻撃力 : main_atk // 防御力 : main_def // 素早さ : main_spe // 賢さ : main_wis // 悪運 : main_luk ed.putInt("main_atk", 3); ed.putInt("main_def", 3); ed.putInt("main_spe", 4); ed.putInt("main_wis", 2); ed.putInt("main_luk", 2); ed.commit(); Intent inte = new Intent(this, Walk.class); startActivity(inte); } }

●「PrefAct.java」

public class PrefAct extends PreferenceActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); System.out.println("接続 : PrefAct"); getSharedPreferences("ch_main", MODE_PRIVATE); // getPreferences(MODE_PRIVATE); // addPreferencesFromResource(R.xml.ch_main); }

●「ch_main.xml」(主人公のデータを登録したいXML)

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <Preference android:title="攻撃力" android:key="main_atk"/> <Preference android:title="防御力" android:key="main_def"/> <Preference android:title="素早さ" android:key="main_spe"/> <Preference android:title="賢さ" android:key="main_wis"/> <Preference android:title="悪運" android:key="main_luk"/> </PreferenceScreen>

長くなってしまいました。申し訳ありません。
「主人公プリファレンス登録メソッド」という文字まではコンソールに出力されるので、「chara_pref.java」に行っているのは行っているのだと思います。
いろいろ試していて余計なコメントアウトがあります。すみません。

###発生したエラー

49.844 2664-2664/hiso.rpg E/AndroidRuntime: FATAL EXCEPTION: main Process: hiso.rpg, PID: 2664 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference at android.content.ContextWrapper.getPackageName(ContextWrapper.java:132) at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:374) at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:369) at hiso.rpg.chara_pref.chara_main(chara_pref.java:35) at hiso.rpg.First$DialogFragGirl$1.onClick(First.java:120) at android.view.View.performClick(View.java:4780) at android.view.View$PerformClick.run(View.java:19866) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

エラーが出ている「First.java」の120行目は cp.chara_main("girl");
「chara_pref.java」の35行目は startActivity(new Intent(this, PrefAct.class));

表示される2つのボタンのうち「女の子」をクリックし、進んだ場合のエラーです。
「男の子」をクリックしても同じエラーが出ます。

###補足情報(言語/FW/ツール等のバージョンなど)
Java / Android Studio / Nexus 7 で動作確認中

初心者なのでいろいろと間違っているかもしれませんが、お手柔らかにご教授くださると嬉しいです。
どうぞよろしくお願いいたします。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abs123

2016/07/25 02:16

chara_prefが何を継承しているか知りたいので、chara_pref.javaの全文を載せてください。
Hiso0802

2016/07/25 02:27

コメントありがとうございます。 「chara_pref.java」の部分を修正いたしました。 どうぞよろしくお願いいたします。
guest

回答3

0

いろいろ問題があるような気がしますが、
とりあえずこれだけ言っておきます。
「~Activityは、プログラマがnewしてはいけない」
ということです。(Activity以外にも結構ありますが・・・)

「~Activity」とつくクラスは、システム側で生成することを想定して実装されているため、
プログラマがnewした「~Activity」を使用すると、予期せぬ動作を引き起こすことになります。

今回問題も、PreferenceActivityを継承したchara_prefが、プログラム側でnewされています。

chara_prefが生成された後、chara_pref.chara_mainの処理で、
PreferenceManager.getDefaultSharedPreferencesの引数に、
自身が持つContext情報をthisで渡していますが、
正規の初期化手順(システム側が生成すること)を踏んでいないため、
PreferenceManager.getDefaultSharedPreferences内部の処理で、
情報の不足/不整合が発覚し、NullPointerExceptionが発生した、というのが今回の流れです。

投稿2016/07/25 03:00

abs123

総合スコア1280

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hiso0802

2016/07/25 03:13

ご回答ありがとうございます。 Activityをnewしてはいけなかったのですね…ご説明ありがとうございます。 DialogFragmentを継承しているDialogFragGirl内ではIntentが使用できず、このような方法をとってchara_prefにアクセスしてみたのですがそれが原因だとは思わず、「chara_pref.java」ばかりを修正していました… newを使わず、どのような方法で別Activityにアクセスできるのかもう少し模索してみたいと思います。
abs123

2016/07/25 05:16

>>Intentが使用できない コールバック用のinterfaceを作って、 onClickが押されたときに処理を大本のクラスに返す、というのはどうでしょう? ChooseMainの立ち位置が少し怪しい気がするので、 そこら辺の調整も必要になると思いますが・・・
Hiso0802

2016/07/25 06:33

ありがとうございます。 一応、自分で投稿したIntentのパッケージ名などをStringで指定して遷移する方法で動きましたが、まだ動作がすっきりしないのでコールバックも試してみようかと思います!
guest

0

まず、エラーログの内容はFirst.javaの120行目でNullPointer例外が発生しています。その行はどこですか?

また、下記は指摘です。できれば修正して、質問も書き換えてくれると分かりやすくなると思います。

  • クラス名が抽象的過ぎてなにをするクラスか分かり辛い
  • 各コード片がどのようなクラスに属しているかわからない、質問する時はクラス宣言部を省略すべきではない
  • メソッド名はキャメルケースに統一しましょう。

投稿2016/07/25 02:32

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hiso0802

2016/07/25 02:59

ご回答ありがとうございます。 yona様のコメントを見ながら質問内容を編集いたしました。 字数の関係でコードを全て載せることができず割愛している箇所もあり、また私がプログラミング初心者、このサイトを使うのも初めてなので見づらいところや意味が分からないところもあるかと思いますがご容赦いただきたく思います…申し訳ございません。 どうぞよろしくお願いいたします。
yona

2016/07/25 03:04

読み易くなりました。ありがとう。 dialogboy.xmlの中にbuttonと言うidのButtonは存在しますか?
Hiso0802

2016/07/25 03:17

こちらこそありがとうございます。 これから質問を書く際の参考となりました。 dialogboy.xml、またdialoggirl.xmlの中にbuttonというidのボタンは存在します。 ------ <Button android:id="@+id/button" android:text="これで始める" android:textSize="20sp" android:textColor="#00f" android:layout_margin="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> ------
yona

2016/07/25 03:21

勘違いでした。 Activityはプログラマーがインスタンス化できるクラスではありません。 Intentを使ってOSにインスタンス化を依頼する必要があります。
Hiso0802

2016/07/25 04:38

ありがとうございます。 DialogBoy、またDialogGirlがDialogFragmentを継承していることでstaticとなり、Intentが使用できない(というよりはFirst.thisが使えない)のですが、これの解決法はあるのでしょうか? 自分でも調べてはいるのですが分からず…
yona

2016/07/25 06:01

staticにしている意味はなんでしょうか? あと、onCreateDialogでshowする必要は無いですよ。
Hiso0802

2016/07/25 06:36

DialogFragmentを継承するとstaticにしないといけないようで(そのような注意文が出ます)、カスタムダイアログ生成で調べたものがFragmentを使うものだったので使っています。 showする必要ないのですね…調べたところでshowしてあったので私もshowしてみたのですが、要らない処理をしたくはないので消します! ありがとうございます。
yona

2016/07/25 06:51 編集

「警告文の通りに修正して解消したからそれが正解だ」という考え方は危険です。 今後、DialoFragmentを継承したらstaticを付けるつもりですか? 「メンバークラス インナークラス static」で調べましょう。 また、女と男でダイアログを分ける理由はなんでしょうか。ダイアログのコンストラクタに引数を渡すだけで解決しますよ。
Hiso0802

2016/07/27 02:56

そうですよね…ご指摘ありがとうございます。 ただ、ダイアログのカスタムレイアウトがDialogFragmentを継承する方法しか出てこなかったので(私の調べ方が悪いのかもしれませんが)、そうするものなんだと思っておりました。 ダイアログを2つに分けているのは、当初は1つだったのですがそれでは何かがエラーで思う通りにできなかったので分けて試してみた結果です。でも、1つではできないということ自体が今思うと変なのでそこは書き直そうと思っています。
guest

0

DialogFragBoy また DialogFragGirl の OnClick に

String packName = "hiso.rpg"; String className = chara_pref.class.getCanonicalName(); Intent intent = new Intent(); intent.setClassName(packName, className); intent.putExtra("sx", "girl"); // FragBoyの場合は"boy" startActivity(intent);

と書くことで、一応staticクラス内でもIntentすることができ、動作しました!
abs123様にお答えいただいたコールバックの方法など、いろいろ試してみたいと思います。

投稿2016/07/25 06:31

編集2016/07/25 06:39
Hiso0802

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問