【Android】アノテーション @SharedPref を使う

Androidアプリケーションで設定などの値を保存する際に、アノテーションを利用して簡単に読み書きする方法をまとめてみます。

まずは通常の SharedPreferences クラスを利用する例が以下です。

SharedPreferencesクラスを使った例

// SharedPreferencesクラスを実体化
SharedPreferences preferences = getSharedPreferences("data", Context.MODE_PRIVATE);

// IDを読み込み
int id = preferences.getInt("id", 0);

// IDを書き込み
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("id", 123);
editor.apply();

これをアノテーション @SharedPref を使って書くと次のようになります。

@SharedPrefを使った例

// ※これはメンバー変数
@Pref
static MyPreference_ preference;

// IDを読み込み
int id = preference.id().get();

// IDを書き込み
preference.id().put(123);

Editorを作ったり、keyを指定したりしなくていいのでだいぶすっきりします。

保存する設定値が多くなればなるほど、使いやすさが実感できると思います。

ただしこれを利用するにはもちろん前準備が必要になるので説明します。

前準備

ライブラリを追加

app/build.gradle

dependencies { … } に以下の2行を追加します。

annotationProcessor "org.androidannotations:androidannotations:+"
implementation "org.androidannotations:androidannotations-api:+"

SharedPrefインターフェースを作成

以下のようなインターフェイスを作成します。

MyPreference.java

package com.example.preftest;

import org.androidannotations.annotations.sharedpreferences.SharedPref;

@SharedPref(value=SharedPref.Scope.APPLICATION_DEFAULT)
public interface MyPreference {
    int id();
}

※idは変数ではなくメソッドとして定義します。

この状態で、メニューの [Build] -> [Clean Project] -> [Rebuild Project]の順に実行します。

するとコンパイラによって MyPreference_ が生成されます。

これで冒頭で紹介したような書き方が可能になります。

初期値を設定する

MyPreference.java

ShereadPreferencesクラスを使った場合、preferences.getInt("id", 0); のように初期値を設定できるので、これと同じことをしたい場合は次のようにコードを修正します。

// 初期値:0
@DefaultInt(0)
int id();

設定値が未設定だった場合に適用する初期値は @DefaultXXX を使います。(XXXは型名がはいる)

Rebuildでエラーが発生した場合

Java Compilerで下記のようなエラーが発生する場合があります。

シンボルを見つけられません

 Compilation failed; see the compiler error output for details.

 エラー: シンボルを見つけられません
 シンボル:   クラス MyPreference_
 場所: クラス MainActivity

 Execution failed for task ':app:compileDebugJavaWithJavac'.
 ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
 ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
 (省略)
 ... 32 more

このエラーはインターフェース(この例ではMyPreference)の構文に問題があり、MyPreference_を生成できないためにあります。

その結果MyPreference_というシンボルが存在しないためエラーになります。

※どこに問題があるかまでは、エラー内容からは分かりません。

Element preference invalidated by PrefHandler

Compilation failed; see the compiler error output for details.
 警告: Element preference invalidated by PrefHandler
 エラー: org.androidannotations.annotations.sharedpreferences.Pref can only be used in a class annotated with 
 @org.androidannotations.annotations.EApplication, @interface org.androidannotations.annotations.EActivity, @interface 
 org.androidannotations.annotations.EViewGroup, @interface org.androidannotations.annotations.EView, @interface 
 org.androidannotations.annotations.EBean, @interface org.androidannotations.annotations.EService, @interface 
 org.androidannotations.annotations.EIntentService, @interface org.androidannotations.annotations.EReceiver, @interface 
 org.androidannotations.annotations.EProvider, @interface org.androidannotations.annotations.EFragment.

このエラーはアクティビティでMyPreference_をアクティビティで使用しているために発生します。

@EFragmentをアノテーションにおいたフラグメントで使用しなくてはならないという決まりがあります。

アクティビティで使用したい場合はフラグメント経由で使用すればOK。

Fragmentを使う② - ActivityからFragmentのメソッドを呼ぶ -

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)