SharedPreferences
キャッシュライブラリ
SharedPreferences
概要
SharedPreferencesは、Androidアプリケーションで小さなキー値ペアのコレクションを保存するためのインターフェースで、自動的にキャッシュされ効率的なデータアクセスを提供します。
詳細
SharedPreferencesは、比較的小さなキー値のコレクションを保存するために使用されるAndroidの標準的なデータ保存機能です。SharedPreferencesオブジェクトは、キー値ペアを含むファイルを指し、それらを読み書きするためのシンプルなメソッドを提供します。各SharedPreferencesファイルはフレームワークによって管理され、プライベートまたは共有可能です。重要な特徴として、SharedPreferencesは自動的にキャッシュされます。特定のSharedPreferencesへの最初のアクセス時にXMLファイルがロードされ、その後の読み取りはキャッシュから動作するため、非常に効率的です。アプリケーション設定、ユーザー設定、簡単な状態情報の保存に適しています。
メリット・デメリット
メリット
- 自動キャッシュ: フレームワークが自動的にキャッシュを管理
- 高速アクセス: 初回ロード後はメモリキャッシュから高速読み取り
- シンプルAPI: 直感的で使いやすいメソッド群
- 型安全: 型別のgetterメソッドでタイプセーフな操作
- 永続化: アプリ再起動後もデータが保持される
- アトミック操作: commitとapplyによる安全な書き込み
デメリット
- 小データ向け: 大容量データには不向き
- XML形式: 複雑なデータ構造は保存できない
- メインスレッド: 同期操作はメインスレッドをブロック
- 型制限: プリミティブ型とStringのみサポート
- 非推奨: DataStoreが推奨される新しい代替手段
主要リンク
- SharedPreferences | Android Developers
- データ保存ガイド | Android Developers
- DataStore移行ガイド
- GeeksforGeeks SharedPreferences
書き方の例
基本的な使用方法
// SharedPreferencesインスタンスの取得
SharedPreferences sharedPref = getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE);
// データの保存
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("username", "john_doe");
editor.putInt("user_age", 25);
editor.putBoolean("is_logged_in", true);
editor.apply(); // 非同期で保存
// データの読み取り
String username = sharedPref.getString("username", "");
int age = sharedPref.getInt("user_age", 0);
boolean isLoggedIn = sharedPref.getBoolean("is_logged_in", false);
Activity でのデフォルト SharedPreferences
public class MainActivity extends AppCompatActivity {
private SharedPreferences prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// デフォルトのSharedPreferencesを使用
prefs = PreferenceManager.getDefaultSharedPreferences(this);
// 初回起動チェック
if (isFirstLaunch()) {
showWelcomeScreen();
setFirstLaunchCompleted();
}
}
private boolean isFirstLaunch() {
return prefs.getBoolean("first_launch", true);
}
private void setFirstLaunchCompleted() {
prefs.edit()
.putBoolean("first_launch", false)
.apply();
}
}
ユーザー設定の保存と読み込み
public class SettingsManager {
private static final String PREFS_NAME = "AppSettings";
private static final String KEY_THEME = "theme";
private static final String KEY_NOTIFICATIONS = "notifications_enabled";
private static final String KEY_LANGUAGE = "language";
private Context context;
private SharedPreferences prefs;
public SettingsManager(Context context) {
this.context = context;
this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
// テーマ設定
public void setTheme(String theme) {
prefs.edit()
.putString(KEY_THEME, theme)
.apply();
}
public String getTheme() {
return prefs.getString(KEY_THEME, "light");
}
// 通知設定
public void setNotificationsEnabled(boolean enabled) {
prefs.edit()
.putBoolean(KEY_NOTIFICATIONS, enabled)
.apply();
}
public boolean isNotificationsEnabled() {
return prefs.getBoolean(KEY_NOTIFICATIONS, true);
}
// 言語設定
public void setLanguage(String language) {
prefs.edit()
.putString(KEY_LANGUAGE, language)
.apply();
}
public String getLanguage() {
return prefs.getString(KEY_LANGUAGE, "en");
}
}
セッション管理
public class SessionManager {
private static final String PREF_NAME = "UserSession";
private static final String KEY_IS_LOGGED_IN = "isLoggedIn";
private static final String KEY_USER_TOKEN = "userToken";
private static final String KEY_USER_ID = "userId";
private static final String KEY_LOGIN_TIME = "loginTime";
private SharedPreferences pref;
private SharedPreferences.Editor editor;
private Context context;
public SessionManager(Context context) {
this.context = context;
pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
editor = pref.edit();
}
public void createLoginSession(String token, String userId) {
editor.putBoolean(KEY_IS_LOGGED_IN, true);
editor.putString(KEY_USER_TOKEN, token);
editor.putString(KEY_USER_ID, userId);
editor.putLong(KEY_LOGIN_TIME, System.currentTimeMillis());
editor.commit(); // 即座に保存
}
public boolean isLoggedIn() {
return pref.getBoolean(KEY_IS_LOGGED_IN, false);
}
public String getUserToken() {
return pref.getString(KEY_USER_TOKEN, null);
}
public String getUserId() {
return pref.getString(KEY_USER_ID, null);
}
public void logoutUser() {
editor.clear();
editor.apply();
// ログイン画面にリダイレクト
Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
public boolean isSessionExpired() {
long loginTime = pref.getLong(KEY_LOGIN_TIME, 0);
long currentTime = System.currentTimeMillis();
long sessionDuration = 24 * 60 * 60 * 1000; // 24時間
return (currentTime - loginTime) > sessionDuration;
}
}
Kotlinでの使用例
class PreferenceHelper(context: Context) {
companion object {
private const val PREF_NAME = "MyAppPrefs"
private const val KEY_USER_NAME = "user_name"
private const val KEY_USER_EMAIL = "user_email"
private const val KEY_IS_FIRST_RUN = "is_first_run"
}
private val prefs: SharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
var userName: String
get() = prefs.getString(KEY_USER_NAME, "") ?: ""
set(value) = prefs.edit().putString(KEY_USER_NAME, value).apply()
var userEmail: String
get() = prefs.getString(KEY_USER_EMAIL, "") ?: ""
set(value) = prefs.edit().putString(KEY_USER_EMAIL, value).apply()
var isFirstRun: Boolean
get() = prefs.getBoolean(KEY_IS_FIRST_RUN, true)
set(value) = prefs.edit().putBoolean(KEY_IS_FIRST_RUN, value).apply()
fun clearAllData() {
prefs.edit().clear().apply()
}
}
// 使用例
class MainActivity : AppCompatActivity() {
private lateinit var prefHelper: PreferenceHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
prefHelper = PreferenceHelper(this)
// データの読み書き
prefHelper.userName = "John Doe"
val name = prefHelper.userName
if (prefHelper.isFirstRun) {
// 初回起動時の処理
setupFirstRun()
prefHelper.isFirstRun = false
}
}
}
リスナーを使った変更監視
public class PreferenceWatcher implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences prefs;
public void startWatching(Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.registerOnSharedPreferenceChangeListener(this);
}
public void stopWatching() {
if (prefs != null) {
prefs.unregisterOnSharedPreferenceChangeListener(this);
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
switch (key) {
case "theme_setting":
String newTheme = sharedPreferences.getString(key, "light");
applyTheme(newTheme);
break;
case "notification_enabled":
boolean notificationsEnabled = sharedPreferences.getBoolean(key, true);
updateNotificationSettings(notificationsEnabled);
break;
case "language_setting":
String language = sharedPreferences.getString(key, "en");
updateLanguage(language);
break;
}
}
private void applyTheme(String theme) {
// テーマ変更処理
}
private void updateNotificationSettings(boolean enabled) {
// 通知設定変更処理
}
private void updateLanguage(String language) {
// 言語変更処理
}
}
暗号化されたSharedPreferences
// EncryptedSharedPreferencesの使用(API 23+)
public class SecurePreferenceManager {
private static final String FILE_NAME = "encrypted_prefs";
private SharedPreferences encryptedPrefs;
public SecurePreferenceManager(Context context) {
try {
MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
encryptedPrefs = EncryptedSharedPreferences.create(
context,
FILE_NAME,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
} catch (Exception e) {
e.printStackTrace();
// フォールバック:通常のSharedPreferences
encryptedPrefs = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
}
}
public void saveSecureData(String key, String value) {
encryptedPrefs.edit()
.putString(key, value)
.apply();
}
public String getSecureData(String key, String defaultValue) {
return encryptedPrefs.getString(key, defaultValue);
}
}