15 min/d

ぼうずやのにっき

Android の Loader や LoaderManager を調べる

bouzuya/bbna をつくっている。 bbna は blog.bouzuya.net for AndroidAndroid のアプリで、 blog.bouzuya.net の client だ。目的は Android アプリ開発の練習だ。諸事情で Android アプリ開発ができないといけなくなったからだ。

進捗は blog.bouzuya.net の記事の一覧を表示するところまでを 2017-04-102017-04-11 で、記事の詳細を表示するところを 2017-04-12 と今日でやってきた。ひとまず記事の詳細を表示できるようになったが、まだこのつくりで良いのか迷っている。

Loader / LoaderManager でまだ迷っている。

Loader2017-04-10 でも出てきたが、 API ガイドの Loader のページ を読んで、また見方が変わってきた。名前から読み込みをするだけかと思ったのだけど、読み込んだデータの保持もするように見える。 Activity はデータを保持せず、 Loader (+ LoaderManager) 経由でデータを受け取る感じ。 Adapter にそのまま渡せばいいっぽいけど、そのあたりはまだよく分かっていない。

Activity にはひとつの LoaderManager があり、ライフサイクルに応じてよしなに Loader を管理してくれる。 LoaderCallbacks 経由で結果を受け取る。 Activity が直接それを実装すると、戻り値の型が制限されるので、独自の callback を実装して LoaderCallbacks からそれを呼ぶようにする。

LoaderManager.LoaderCallbacks<Result<List<Entry>>> callbacks =
    new LoaderManager.LoaderCallbacks<Result<List<Entry>>>() {
      @Override
      public Loader<Result<List<Entry>>> onCreateLoader(int id, Bundle args) {
        // ...
      }

      @Override
      public void onLoadFinished(
        Loader<Result<List<Entry>>> loader,
        Result<List<Entry>> data
      ) {
        MainActivity.this.onLoadEntryListFinished(data); // 独自の callback
      }

      @Override
      public void onLoaderReset(Loader<Result<List<Entry>>> loader) {
        // ...
      }
    };
LoaderManager loaderManager = getSupportLoaderManager();
loaderManager.initLoader(ENTRY_LIST_LOADER_ID, null, callbacks);

LoaderManager 経由では操作もほとんど初期化のことをできない。いつ読み込みを開始するかの制御はない。必要なら initLoaderrestartLoader で初期化し直す感じ。 Activity のライフサイクルに合わせて制御されるので任せてしまい、初期化したら取得してくれるのを待つだけという雰囲気っぽい。

課題が多い。

『それはオレの魚だ』で遊んだとか

今日は Android の WebView を試してみた。意外と簡単に表示できるので良さそうだ。……とは言え、もともとそういう想定をしていない Web ページだし、また Loader をつくらないといけなさそうなので、もうすこし時間がかかるだろう。

話は変わる。

昨日の記事 (2017-04-11) に書きそびれたのだけど、『それはオレの魚だ』で遊んだので、そのことを書く。家族の 3 人で遊んだ。

『それはオレの魚だ』は、ペンギンが魚を集めるゲームだ。

ルールは簡単だ。1 〜 3 匹の魚が描かれた氷タイルを集める。最終的に一番多くの魚を集めれば勝ち。六角形の氷タイルは 60 個あり、 878787… と並べる。ペンギンコマをひとつずつ順番に 1 匹の魚が描かれたタイルを選んで配置する。人数によるが盤面全体に対して 8 〜 9 のコマが配置される。全員が配置し終えたらゲームスタート。順番にコマを移動させて、移動する前にコマがあったところのタイルを入手する。移動はコマがある場所から直線に移動する。ただし他のコマや氷が途切れていると移動できない。全員が動けなくなったら終了。最後にコマが居た位置のタイルも入手できる。

目的が明確だし、移動の規則も難しくない。ただ氷タイルの初期配置とプレイの順番くらいで運の要素がほとんどないので実力差がかなり出そうだ。ルールは違うけど、囲碁ブロックスなどと同じ系統だ。難しい。長考してしまうので、タイマーを置いたほうが良いかもしれない。

名前のとおりだけど、「それはオレの魚だ」と言わんばかりに相手と奪い合う感じ。良い。

Android で JSON を parse する

昨日 (2017-04-10) に続き、bouzuya/bbna をつくっている。通信して取得した JSON を表示するところまで来た。

JSONArrayJSONObject でなんとかする感じ。明日は WebView に手を出せるかな。今週中に公開まで行きたいので、適当に切り上げて進まないとな……。

Android HttpURLConnection とか

bouzuya/bbna をつくっている。いまは通信処理を書いている。よく分からないままに書いている。

Java は同期的に通信ができるので……いや、さすがにメインスレッドで通信処理もまずい。非同期処理だ。 Loader というコンポーネントを使う。Loader の一種である AsyncTaskLoader を使う。

Loader は Support Package の LoaderManager 経由で使っている。Loader がひとつしかないのに LoaderManager が要るのか分からないけど、再利用がどうとか書いてあるのでうまく管理してくれるのだろう。結果を受け取るために MainActivityLoaderManager.LoaderCallbacks を実装する。うーん。

AsyncTaskLoaderloadInBackground では HttpURLConnection を使って通信処理を書く。昔は HttpClient がどうのこうのという記述を見かけるが、6.0 で削除されたらしい ので、 HttpURLConnection を使う。サードパーティにもっと便利なのもありそうだけど、とりあえず標準で。

InputStream って懐かしいな。そして面倒くさいな。InputStreamInputStreamReader で wrap して BufferedReader で wrap して……。ああ面倒くさい。検査例外。 IOException 。面倒くさい。Log.e() で吐きつつ、とりあえずは無視。 Stringnull が含まれている……、うーん。……いま書いていて、そういえば、もう Maybe 相当の class がある気がしてきた……。気にせず @Nullable@NonNull をつけつつ進める。この annotation に意味があるのか……。

明日は JSON を parse する感じかな……。


そういえば、『スーパーマリオ ラン』のスペシャルコースを除いてすべてのカラーコインを集めた。カラーコインはピンクコイン・パープルコイン・ブラックコイン。1 コース 3 カラーコイン、 1 ワールド 4 コース、6 ワールド 24 コース 72 カラーコイン。最後はワールド 4-1 ガリガリタワーのブラックコインだった。 2 枚目の P スイッチは二個目のブロックを飛び越えて反対側に行けば良かった。1 枚目と同様に時間的にギリギリなので厳しい。 5 枚目も難しいが、シャボンを十分集めていれば何回か挑戦できるので、それほどでもなかった。

2017-W14 ふりかえり

2017-W14 をふりかえる。

2017-04 の目標

2017-W14 の目標

Android の学習を進めている。

今週の記事

つくったもの

2017-04-03/2017-04-09

Android のアプリ開発について調べている。ただ何かをつくったわけではない感じ。一応 bbna : blog.bouzuya.net for Android を題材に練習していくつもりだ。

その他

スーパーマリオ ラン』はあとすこしで終わりそうだ。第一印象については 2017-04-04 に書いた。残りは次のとおりだ。

  • ワールド 4-1 (ガリガリタワー) のブラックコイン
  • スペシャルコース (パープルコイン) のクリア
  • スペシャルコース (ブラックコイン) の取得・クリア
  • すべての建物 (キノピオ) の収集

このところゲームをしているのだけど、『斑鳩』→『スーパーマリオ ラン』と遊んでいて、妻を巻き込まない形はあまり良くない気がしている。これが終わったら、みんなでできるものに回帰しようかな。

プログラミングの基礎概念』を読み終えた (2017-04-06) ので、『アンダースタンディング コンピュテーション』を読みはじめている。第一章・第二章を読んだ。 Ruby への嫌悪感から気持ちが削がれている。すこしずつでも進めよう。ただ Android のほうが優先なので、うまく進まないかもしれない。

2017-W15 の目標

  • [ ] bbna : blog.bouzuya.net for Android を公開する
  • [ ] スーパーマリオ ランを終える
  • [ ] 『アンダースタンディング コンピュテーション』を進める

雑多な日記

今日は何をしていただろう。雑多な感じだ。

AndroidMixihttps://github.com/mixi-inc/AndroidTraining をすこしだけ進めた。 Activity と Fragment でいろいろ脱線してくたびれてしまった。本当はこれを終わらせるくらいの気持ちだったのだけど、気持ちだけだった。良くない。

正座椅子が届いた。正座用の座椅子だ。足を体重で圧迫しないのは良い。猫背になっては元も子もないので、意識して伸ばす。あとは横幅がせまいので、股関節が固まってしまいそうだ……。時間を区切って伸ばすようにしないと……。

あわせて本が届いた。『プログラム意味論』・『計算論 計算可能性とラムダ計算』・『論理と計算のしくみ』の 3 冊。パラパラと眺める。

読みはじめたばかりの『アンダースタンディング コンピュテーション』のあとに読んでいくか、あるいは『型システム入門』のあとか……。『アンダースタンディング コンピュテーション』 Ruby を見ると、やる気がなくなる。本を変えたい気持ちになってきた。

収納ケースをまた買いに行った。今度はすこし小さいものを入れられるケースを。それに肌着やらをしまって、合わせて冬物を片付けた。棚をひとつ潰してクローゼットに納めた。部屋の風通しが良くなった。良いことだ。

整理ついでに昔の書類をいくらか処分した。思い切りが足りないので、まだまだ残っている……。

スーパーマリオ ランをクリアした。クッパを倒したのでクリアだろう。ワールド 6 まではワールド 4-1 のガリガリータワーのブラックコインを除いてコンプリートした。あとはガリガリタワーとワールド 6 とスペシャルコース。キノピオも集めないとな……。基本的にはマリオで、ヨッシールイージを必要に応じて使っている。一撃は耐えられるのがマリオ・ルイージの利点で、ルイージはジャンプの高さが足りないとき、ヨッシーはトゲが嫌なときに使っている。ステージがマリオ基準につくられているのか、ルイージのジャンプだと歩幅が合わないことが多いので、基本はマリオにしている。

ああ、雑多だ。