プリファレンス

■Androidのデータ保存方法

	Androidのデータ保存方法は以下の方法があります。
		・プリファレンス
			Androidの内部記憶媒体にKey-Value形式でデータを記録する方法です。
			記録できるデータの形式やデータ量に制限があるので、
			アプリの設定値などの小規模な情報を記憶する際に使用します。

		・データファイル
			長文を保存してあるテキストデータや画像や音などの
			バイナリデータの保存もできます。
			サイズの大きなファイルを保存する際に使用します。

		・SQLite
			大量のデータを扱う際に使用する方法です。
			SQLiteはデータベースの一種で、サーバーではなくアプリ側に
			データベースを組み込んで使用します。
			MySQLなどのデータベースに比べ軽量化されており、
			速度も中、小規模のデータ量なら遜色がありません。

	今回はプリファレンスによる使用方法の説明をします。

■準備

	事前準備として以下の手順を実行して下さい。

	①.プロジェクト作成
		新規プロジェクト「DataSaveTest」をEmptyActivityで作成します。

	②.HelloWorld削除
		作成後はProjectウィンドウのres/layout/activity_main.xmlを
		クリックしてXMLを表示してHello WorldのTextViewタグを削除します。
	
	③.テキストエディタ追加
		3-1.テキスト入力欄追加
			Paletteの「Palin Text」を追加します。
			※サイズが小さければ「横300」「縦50」で調整する

		3-2.テキスト追加
			Propertiesの「Text」欄に「入力欄」と設定します。

		mb_0068

	④.ボタン追加
		4-1.ボタン追加
			プリファレンス用で使用するボタンを二つ追加します。

		4-2.ボタンテキスト変更
			ボタンのテキストを「プリ読み込み」「プリ書きこみ」に変更します。

		4-3.id変更
			ボタンのidを「プリ読み込み」は「preRead」
			「プリ書きこみ」を「preWrite」に変更します。

		mb_0071

	⑤.ボタンのクリック設定
		5-1.アクティビティにOnClickListenerの継承
			アクティビティにOnClickListenerを継承します。
			※android.view.Viewをimportして下さい

			例:
				public class MainActivity extends AppCompatActivity 
							implements View.OnClickListener {

		5-2.onClickを定義
			onClickを定義します。

			例:
				@Override
				public void onClick(View v)
				{
				}

		5-3.ボタン毎の分岐作成
			④と⑤のボタンで設定したボタンの処理を行えるように
			onClick内に分岐処理を追加します。

			例:
				switch (v.getId())
				{
					case R.id.preRead:
						break;
					case R.id.preWrite:
			 			break;
				}

		5-4.通知設定
			アクティビティにボタンがクリックされた通知が行くように
			設定を行います。

			// onCreate関数内
			findViewById(R.id.preRead).setOnClickListener(this);
			findViewById(R.id.preWrite).setOnClickListener(this);

■プリファレンス

	プリファレンス(Preference)キーと値の組み合わせでデータを保存する方法です。
	データの実体はXML形式のテキストファイルとして保存されています。
	プリファレンスで使用できる型は以下の通りです。
		・boolean
		・float
		・int
		・long
		・String

	●プリファレンスのアクセス方法
		プリファレンスにアクセスするにはgetSharedPreferences()関数SharedPreferencesオブジェクトを取得(作成)することで可能となります。
		
		・getSharedPreferences
			戻り値:
				SharedPreferencesオブジェクト
			引数:
				第一:
					String:プリファレンス名

				第二:
					int:アクセスモード

					MODE_PRIVATE => このアプリのみアクセス可能
					MODE_APPEND => 追記
			内容:
				指定したプリファレンス名のSharedPreferencesオブジェクトを取得し、
				該当名前のプリファレンスがなければ新規で作成されます。
				アクセスモードにはアプリのみアクセス可能な
				MODE_PRIVATE(新規作成)と追記モードのMODE_APPENDがあります。

			例:
				SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);

	●書き込み方法
		書きこみを行うには、まず編集用オブジェクトEditorを取得し、
		次に書き込みたい内容をEditorオブジェクトに追加していきます。
		最後に書きこみ内容を反映して終了です。

		①.Editorオブジェクト取得
			取得したプリファレンスにデータを書き込むには
			データ書き込み用オブジェクトのEditorをプリファレンスから
			取得する必要があります。
			取得のための関数としてedit関数が用意されています。

			・edit
				戻り値:
					Editorオブジェクト
				引数:
					なし
				内容:
					プリファレンスオブジェクトの編集用オブジェクトEditorを返す

				例:
					SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);
					SharedPreferences.Editor editor = sp.edit();

		②.書き込み
			データの書き込みはEditorオブジェクトのメンバ関数である
			「put~関数」を使用します。
			「~」の部分には設定できる型の名前を指定します。

			putString:
				戻り値:
					Editor:書き込たいデータを追加したEditorオブジェクト
				引数:
					第一:
						String:このパラメータのキー
					第二:
						String:登録文字列
				内容:
					引数に指定したキーで文字列を追加する

				例:
					SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);
					SharedPreferences.Editor editor = sp.edit();
					editor.putString("test_str", "テスト文字列");

		③.反映
			put~関数はあくまでデータをEditorに追加するだけです。
			最終的にSharedPreferencesを通してアプリに保存するためには
			データをアプリに反映するcommitまたはapply関数を使用する必要があります。

			commit:
				戻り値:
					boolean:反映の成否
						true:成功
						false:失敗
				引数:
					なし
				内容:
					editorに設定されているデータをアプリに保存します。
					commit関数は同期処理なので反映が完了しない限り
					処理を先に進めることができません。
				例:
					SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);
					SharedPreferences.Editor editor = sp.edit();
					editor.putString("test_str", "テスト文字列");
					editor.commit();

			apply:
				戻り値:
					なし
				引数:
					なし
				内容:
					editorに設定されているデータをアプリに保存します。
					非同期にデータを反映するので終了を待たずに
					処理を先に進めることができます。
				例:
					SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);
					SharedPreferences.Editor editor = sp.edit();
					editor.putString("test_str", "テスト文字列");
					editor.apply();

			・commitとapplyの違い
				commitとapplyの1番の違いは同期か非同期かです。
				書き込みはデータをアプリに反映させるので処理コストが重めです。
				ですので、処理停止が起きないapplyを使用した反映方法を作成するほうが
				アプリとしては魅力的かと思います。

	●読み込み方法
		読み込みは書き込みとは違い、SharedPreferencesから直接取得します。
		読み込みには書き込みのような反映処理はありません。

		①.読み込み
			読み込みたいデータの取得にはSharedPreferencesオブジェクトの
			メンバ関数である「get~関数」を使用します。
			書き込み関数の「put~」と同様に「get~」の「~」の部分は
			読み込みたいデータの型を記述します。

			getString:
				戻り値:
					成功:String:データ
					失敗:String:第二引数で指定した値
				引数:
					第一:
						String:データに指定してあるキーワード
					第二:
						String:取得失敗時の初期値
				内容:
					SharedPreferencesに設定してあるデータを
					キーワードを指定して取得します。
					もし、該当するキーワードのデータが存在しない場合は
					第二引数で指定した値を返します。

				例:
					SharedPreferences sp = getSharedPreferences("test", MODE_PRIVATE);
					String str = sp.getString("test_str", "エラー");

■サンプル

	MainActivity.javaでonClick関数の実装とWrite、Read関数を追加しています。
	
	// 書き込み
	private void Write()
	{
		EditText edit_text = (EditText)findViewById(R.id.editText);
		String text = edit_text.getText().toString();

		SharedPreferences shared = getSharedPreferences("test", MODE_APPEND);
		SharedPreferences.Editor edit = shared.edit();
		edit.putString("test_str",  text);
		edit.apply();
	}

	// 読み込み
	private void Read()
	{
		EditText edit_text = (EditText)findViewById(R.id.editText);
		SharedPreferences shared = getSharedPreferences("test", MODE_APPEND);
		edit_text.setText(shared.getString("test_str", ""));
	}

	@Override
	public void onClick(View v)
	{
		switch(v.getId())
		{
		case R.preRead:
			Read();
			break;
		case R.preWrite:
			Write();
			break;
		}
	}

■ライフサイクルを利用

	アプリでデータの読み書きを必要とする処理の場所として
	「アプリ起動時」「アプリ再開時」「アプリ待機時」があります。
	「アプリ起動時」「アプリ再開時」では読み込みを
	「アプリ待機時」では書きこみを行うことで、
	アプリの状況に応じた情報を保存、再開することができます。
	以下の関数は各状況に応じたアプリ内で実行される関数です。

	・onCreate関数
		アプリ起動時に呼び出される関数です。
	・onResume関数
		アプリ再開時に呼び出される関数です。
	・onPause関数
		アプリ待機時に呼び出される関数です。
		アプリ終了時とアプリ待機時で行う処理は同じ処理を行うことが多く、
		データ保存のタイミングとして終了時より、待機する際のほうが
		適していることから待機状態遷移時に書きこみ処理を行います。