【Android】Bundleの使い方
Bundleとは
AndroidにはActivityのライフサイクルがあります。
別のActivityが前面に来るなどにして、メモリが不足した場合にActivityが破棄されることがあります。
このとき、メモリ上にだけ展開されていたインスタンス変数などの値も破棄されてしまいます。
再度呼び出されるときは、もう一度Activityを生成しなおすため、前回の状態は失われています。
そこで、前回と同じ状態に復元できるようにするために、状態を保存、復元するクラスとしてAndroidが準備してくれているのがBundle
です。
簡単に言うとBundle
はOSの判断で強制的に停止、終了する時に一時的にデータを格納するクラスです。
Bundleの使い方
Bundleの作成
Bundle 変数 = new Bundle(); 変数.putString("キー1", "値1"); 変数.putString("キー2", "値2");
値を受け取る場合
String 変数 = args.getString("キー1"); String 変数 = args.getString("キー2");
Bundleの使用例
画面遷移などでも使用できるのですが、今回は同じクラス内の異なるpublic ... { }同士で値を受け渡す処理を書きます。
public clas ... extends ... { @Override public ... { . . . Bundle args = new Bundle();// Bundleの作成 args.putString("key1", "value1");// 渡す値をセット args.putString("key2", "value2");// 渡す値をセット } @Override public ... { . . . String getValue1 = args.getString("key1");//値の受け取り String getValue2 = args.getString("key2");//値の受け取り } }
参考サイト:
【Android】HTTP通信での非同期処理の方法
Android 3.0以降、メインスレッドでネットワーク処理を行うとエラーにるみたいです。
メインスレッドにネットワーク処理を書いてしまうと、NetworkOnMainThreadException
というエラーがでてしまいます。
メインスレッドでHTTP通信を行う場合は、非同期処理をしないといけないみたいです。
そこで、
・AsyncTaskLoader
(非同期処理のロード)
・LoaderCallback
(非同期処理のコールバック)
を使用します。
AsyncTaskLoader
非同期処理(ロード)を行なうために以下ファイル(HttpAsyncTaskLoader.java
)を作成します。
public class HttpAsyncTaskLoader extends AsyncTaskLoader<String> { /** 引数 */ private String mArg; /** 非同期処理での結果を格納 */ private String mData; public HttpAsyncTaskLoader(Context context, String arg) { super(context); this.mArg = arg; } @Override public String loadInBackground() {// 非同期処理を記述 try { // 適当に時間がかかる処理 Thread.sleep(3000); mData = "hoge"; } catch (InterruptedException e) { e.printStackTrace(); } return mData; } @Override protected void onStartLoading() {// 非同期処理の開始前 // ActivityまたはFragment復帰時(バックキーで戻る、ホーム画面から戻る等)に再実行されるためここで非同期処理を行うかチェック if (mData != null) {// 結果がnullではないは場合は既に実行済みとして非同期処理は不要 // deliverResultで結果を送信 deliverResult(mData); } if (takeContentChanged() || mData == null) { // 非同期処理を開始 forceLoad(); } } @Override protected void onStopLoading() {// Loader停止時の処理 // 非同期処理のキャンセル cancelLoad(); } @Override public void deliverResult(String data) {// 登録してあるリスナー(LoaderCallbacksを実装したクラス)に結果を送信 if (isReset()) {// Loaderがリセット状態かどうか // trueの場合はLoaderがまだ一度も開始していない、resetメソッドが呼ばれている return; } mData = data; super.deliverResult(data); } @Override protected void onReset() { // reset呼び出し時、Loader破棄時の処理 super.onReset(); // Loaderを停止 onStopLoading(); // データをクリア mData = null; } }
LoaderCallbacks
以下のコードを追加で、非同期処理の結果を受け取ることができます。
public class QuestionsAndAnswersFragment extends Fragment implements LoaderManager.LoaderCallbacks<String> { . . . private static final int LOADER_ID = 0; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Loaderに渡す引数 Bundle args = new Bundle(); args.putString("hoge", "hoge"); // Loader初期化と開始 getLoaderManager().initLoader(LOADER_ID, args, this); } @Override public Loader<String> onCreateLoader(int id, Bundle args) {// 非同期処理を行うLoaderを生成 // getLoaderManager().initLoaderで一回のみ呼び出される String data = args.getString("hoge1"); return new HttpAsyncTaskLoader(getActivity(), data); } @Override public void onLoadFinished(Loader<String> loader, String data) {// 非同期処理完了時 // ここでView等にデータをセット // ログて返ってきた値を確認 Log.v("tag", data); // Loaderを停止・破棄(次回の読み込みでもう一度initLoaderをできるようにするため) getLoaderManager().destroyLoader(loader.getId());// loader.getId() == LOADER_ID(initLoaderの第一引数) } @Override public void onLoaderReset(Loader<String> loader) {// Loaderが破棄される時に呼び出し // Loaderが参照しているデータを削除する } . . . }
参考サイト: