プログラミングで何か作ってみる

現在プログラミングにハマっている人がツールやゲームを公開するブログ

androidでデータ保存する方法(gson)

どうも!
早速android開発中に引っかかった部分があったのでメモ
※記事中のコードは動作確認していないのでスペルミスあるかも

androidにて設定やデータを保存したいとき、基本的にSQLiteデータベースを使うかSharedPreferenceとかを使ってアプリの固有領域に保存します
でも、正直保存したいデータが自作クラスでまとまってるとき(特に他のクラスを持ってるクラス)、上の2つだと保存が大変です
どちらもキー:値の形で保存するので、大量のクラス変数があるときキーの管理が大変になって行きます
なのでもっとかんたんな方法としてGsonというGoogleさんの便利なライブラリを使って保存すると楽です

Gsonとは

Gsonはクラスをそのままjson形式に変えてくれるものです。
jsonは文字列なのでそのままSharedPreferenceに好きなキー1つを使って保存すればクラスごと保存できます

導入は簡単で以下をbuild.gradle(Module:...)のdependenciesに追加でok
implementation 'com.google.code.gson:gson:2.8.6'
バージョンはその都度最新版に変えてください(執筆時点では2.8.6)

やり方はクラスの種類によって変わります

1.単純なクラス
2.クラスのリスト
3.クラスのリスト(抽象クラス)

1.単純なクラス

GsonによってJsonに変換するのでもちろんJsonにならない値がクラスにあると変換できません
基本的に変換できるのはintなどの数値や、Stringなどの文字列です
変換できるクラス変数しかないものを単純クラスと勝手に言ってます



なのでContext,Drawableなどは保存できません。これらは工夫して保存しなくてはいけません
これは後ほど記事にしようかなって思ってます

保存
MyClass myClass = new MyClass;

Gson gson = new Gson();
String json = gson.toJson(myClass); //MyClassをJsonに変換

//あとはこれをSharedPreferenceで保存するだけ


読み込み
//json = SharedPreferenceから読みだしたjson
Gson gson = new Gson();
MyClass myClass = gson.fromJson(json, MyClass.class); //JsonをMyClassに変換


2.クラスのリスト


単純なクラスのリスト(ArrayList<>)は保存は同じですが読み込みが少し違うだけです

保存
ArrayList<MyClass> myClassList = new ArrayList<>();

Gson gson = new Gson();
String json = gson.toJson(myClassList); //MyClassListをJsonに変換

//SharedPreferenceで保存


読み込み
//json = SharedPreferenceから読みだしたjson
Gson gson = new Gson();
ArrayList<MyClass> myClassList = (ArrayList<MyClass>) gson.fromJson(json, new TypeToken<ArrayList<MyClass>>(){}.getType()); //JsonをMyClassListに変換


どうにかこうにかしてListに変換してるだけです

3.クラスのリスト(抽象クラス)

これが一番ややこしいかもです
抽象クラスで複数のクラスが以下のようになっているとき
public abstract class Shape{
int x, y;
public Shape(x, y){
this.x = x;
this.y = y;
}
}

public Rect extends Shape{
int w, h;
public Rect(x, y, w, h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}

public Cirlce extends Shape{
int radius;
public Circle(x, y, radius){
this.x = x;
this.y = y;
this.radius = radius;
}
}


このShapeクラスのリストにRectもCircleクラスも持っている場合は、読み込む際に分別しないといけません。
やり方としてはGsonに分別処理を追加するだけなのですが、この分別処理をしてくれるクラスはすでにGsonのGithubにあるのでコピーして使いましょう
RuntimeTypeAdapterFactory.java
このクラスの使い方は以下のように簡単に書けます
RuntimeTypeAdapterFactory<Shape> adapter = RuntimeTypeAdapterFactory.of(Shape.class)    //親クラスを登録
.registerSubtype(Rect.class) //子クラスを登録
.registerSubtype(Circle.class);

Gson gson = new GsonBuilder().registerTypeAdapterFactory(adapter).create();
ArrayList<Shape> shapeList = (ArrayList<Shape>)gson.fromJson(json, new TypeToken<ArrayList<Shape>>(){}.getType());

親クラスと子クラスをすべて登録したあとにその分別処理ができるGsonを作ってからJson化すると動作します
ちなみにですが、クラス変数にこういった抽象クラスのリストがある場合も新しいAdapterを作って登録すれば動作します

保存は変わらないので省略

まとめ

最後の方は多少難しいかもしれなかったですが、比較的簡単に保存できるので現状一番便利な方法だと思います
あとはクラスを保存できる形式に変えられるかの勝負なのでそれはまた後ほど

ちなみにUriクラスを保存形式にするのは有志の方が作っているものがあります( UriTypeHierarchyAdapter.java )
GsonBuilderのregisterTypeHierarchyAdapterを使って登録すると動作します
他にもあるかも

参考文献

こちらも見てみよう
gson-list - 開発者ドキュメント
SharedPreferenceに自作クラスオブジェクトを保存する方法(Gsonの使用方法) | Androidアプリ開発
GSONの基本的な使い方 - Qiita
関連記事
スポンサーサイト



コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

この記事へのトラックバックURL
https://pnikki.blog.fc2.com/tb.php/255-eb9891df

 | HOME | 

文字サイズの変更

プロフィール

まっちゃ

Author:まっちゃ
いろいろなゲーム、ツール、プログラミングのTipsを公開しようと思っています
中一からずっとプログラミング。
基本的にフリーソフトしか作っていません
裏では絵描いてます

なお、このブログにて公開されたソフトやフラッシュやソースコードは無断転載禁止です(ただし毎月プログラミングを除く)

公開ゲーム・ツール集リンク

以下のリンクにあります
本気?なやつ

公開ゲーム・ツール集


こちらはシンプルなやつです。現在更新停止中

毎月プログラミング


最新記事

ツリーカテゴリー

Script by Lc-Factory
(詳細:Lc-Factory/雑記)

最新コメント

カウンター

リンク

応援したい方、是非クリックお願いします

FC2Blog Ranking

メールフォーム

名前:
メール:
件名:
本文:

ブロとも申請フォーム

この人とブロともになる

designed by たけやん