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

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

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

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

Android Studio

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

Q&A

解決済

3回答

3871閲覧

Android)タイプ型Arrayデータを保存する方法

navesanta

総合スコア198

Android

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

Android Studio

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

0グッド

0クリップ

投稿2017/09/21 09:36

編集2017/09/21 10:00

StringとStringの2つのデータータイプ型を配列に入れてそれを保存したいと思っています。手順は下記の通りです。

1)まずデータタイプとセッター&ゲッターを作成。
2)次に保存用のSharedPreferencesを使ったPrefManagerを作成。
3)最期にMainActivityにセット。
実行すると

FATAL EXCEPTION: main Process: com.○○○.datatypearrayapp, PID: 2817 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.○○○.datatypearrayapp/com.○○○.datatypearrayapp.MainActivity}: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.get(ArrayList.java:411) at com.○○○.datatypearrayapp.MainActivity.onCreate(MainActivity.java:43) at android.app.Activity.performCreate(Activity.java:6679) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)  at android.app.ActivityThread.-wrap12(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6119)  at java.lang.reflect.Method.invoke(Native Method)

と言うエラーが出て保存した(はず)データが取得できません。
上記エラーは「データが無いよ」と言っているような気がしますが
理由が分かりません。

質問は
1)単体のString型のArrayListを保存する時はJSONArrayに一旦入れてSharedPreferencesで
問題なく保存できるのですが複数のデータ型をJSONArrayに入れることができないのでしょうか?
2)もしできるならPrefManagerのコード記述が間違っている箇所があるでしょうか?
3)もしできないなら他にどういった手法があるでしょうか?
swiftのタプルを配列にするような方法はないのでしょうか?
よろしくお願いします。

環境 os mac
開発環境 Android studio 2.2.3

DataType.java

public class DataType { private String kuji_contents; private String kuji_number; //コンストラクタ public DataType( String kuji_contents, String kuji_number){ this.kuji_contents = kuji_contents; this.kuji_number = kuji_number; } public String getKuji_contents() { return kuji_contents; } public void setKuji_contents(String kuji_contents) { this.kuji_contents = kuji_contents; } public String getKuji_number() { return kuji_number; } public void setKuji_number(String kuji_number) { this.kuji_number = kuji_number; } }

PrefManager.java

public class PrefManager { //ArrayDataListをjsonArrayにして保存するメソッド public static void saveDataList(Context ctx, String key, ArrayList<DataType> list){ JSONArray jsonArray = new JSONArray(); for (int i = 0; i < list.size(); i++){ jsonArray.put(list.get(i)); } SharedPreferences preferences = ctx.getSharedPreferences("PrefFile", Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString(key, jsonArray.toString()); editor.apply(); } //保存されているjsonArrayからArrayListに取得するメソッド public static ArrayList<DataType> loadDataList(Context ctx, String key){ ArrayList<DataType> list = new ArrayList<>(); SharedPreferences preferences = ctx.getSharedPreferences("PrefFile", Context.MODE_PRIVATE); String strJson = preferences.getString(key, ""); if (!strJson.equals("")){ try { JSONArray jsonArray = new JSONArray(strJson); for (int i = 0; i < jsonArray.length(); i++){ list.add((DataType) jsonArray.get(i)); } }catch (Exception e){ e.printStackTrace(); } } return list; } }

MainActivity.java

public class MainActivity extends AppCompatActivity { ArrayList<DataType> dataTypeArrayList; ArrayList<DataType> dataTypeArrayListNext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dataTypeArrayList = new ArrayList<>(); String[] contentData = { "あたり", "はずれ" }; String[] numberData = { "1", "2" }; for (int i = 0; i < contentData.length ; i++) { String kuji_contents = contentData[i]; String kuji_number = numberData[i]; dataTypeArrayList.add(new DataType( kuji_contents, kuji_number )); } PrefManager.saveDataList(getApplicationContext(),"testArray",dataTypeArrayList); dataTypeArrayListNext = PrefManager.loadDataList(getApplicationContext(),"testArray"); Log.d("UAA", String.valueOf(dataTypeArrayListNext.get(0))); } }

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

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

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

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

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

yona

2017/09/21 09:43

エラーログを省略せずに記載してください。
navesanta

2017/09/21 10:01

エラーログを追加しました。よろしくお願いします。
guest

回答3

0

自己解決

yonaさんの回答をヒントに解決策が見えてきました。色々調べ直したところSharedPreferencesはboolean
、String、int、long、float、Set<String>の6通りの型しか保存できず複合のデータタイプ型は保存できないとの事。解決方法としてはJson形式に保存できるGsonなどを使うと良いようです。そちらの方向で試してみます。色々ありがとうございました。

投稿2017/09/22 23:37

navesanta

総合スコア198

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

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

0

まずは試しにこれを試してみてください。

java

1 //ArrayDataListをjsonArrayにして保存するメソッド 2 public static void saveDataList(Context ctx, String key, ArrayList<DataType> list){ 3 JSONArray jsonArray = new JSONArray(); 4 for (int i = 0; i < list.size(); i++){ 5 jsonArray.put(list.get(i)); 6 } 7 SharedPreferences preferences = ctx.getSharedPreferences("PrefFile", Context.MODE_PRIVATE); 8 SharedPreferences.Editor editor = preferences.edit(); 9 editor.putString(key, jsonArray.toString()); 10 editor.commit(); // apply() -> commit()に 11 }]

apply()は非同期にデータを書き込むので、データの書き込みが終わる前にloadDataList()が呼ばれてデータが取得できていない可能性があります。
commit()はスレッドをブロックして同期的にデータを書き込むので、原因がここにあるかを判断することができると思います。

投稿2017/09/22 10:41

編集2017/09/22 10:42
hiramekun

総合スコア428

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

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

navesanta

2017/09/22 20:10

commit()に変更しても状態は変わりません。ログキャットでString.valueofで中身を確認するとやはり[]のみになり、配列の中身が存在していない形になります。
guest

0

まずはあなた自身がデバッグをして「気がする」や「思う」という部分を無くしましょう。

デバッグで確認するべき点は下記の点です。
・プリファレンスにどのような文字列を保存しようとしているのか?
・プリファレンスからどのような文字列が取得できたのか?

投稿2017/09/21 10:31

yona

総合スコア18155

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

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

navesanta

2017/09/22 20:22

>プリファレンスにどのような文字列を保存しようとしているのか? 上記コードに記述していますがString型の2つのデータkuji_contents("あたり"、"はずれ")とkuji_number("1"、"2")をセットにしたデータタイプを配列にして保存しようとしています。 >プリファレンスからどのような文字列が取得できたのか? まずadb shellで確認したところshared_prefsは存在します。 しかしログキャットでstring.valueofを使って出力すると配列の[]のみしか表示されないので データが存在しない=取得できていない形になっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問