fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

Custom ViewがRecyclerViewの何番目にあるかをEspressoでさがす

この記事はEspresso 2.2.2時点のもの。

ポイントは次の二つ。

  • Espresso.onView()にcustom viewのクラスを探すcustom matcherを渡す
    • BoundedMatcherの型引数にcustom viewのクラスを渡してやると便利
    • TreeIterables.breadthFirstViewTraversal(View)でcustom view以下の子ビューをトラバースしてマッチするやつを探す
  • custom assertionで受け取ったcustom viewの親がRecyclerViewなのでRecyclerView#getChildAt(int)に確かめたい子ビューの番号を渡してcustom viewと比較する

作例をGistに書いた。

Espresso for RecyclerView

Github flowを始めた

4月末に会社をやめてからというもの、毎日家でコードを書いているか、アニメを見ながらコードを書く生活をしている。知らないことが多くて進みは良くないが、それでも着実にできあがりつつある。

縁あって5月末に一週間だけインターンさせてもらったのだが、その会社でGithub flowを習ったので趣味プロジェクトの開発にも取り入れることにした。Github実践入門を読んで知ってはいたのだが、当時は使うあてもなく、何がうれしいのかわからなかったので完全に忘れていた。

一人だけでやるので一般的なやり方とは違うかもしれないが、一回まわしてみて「こういう感じかな」というのがなんとなく見えてきたのでメモしておく。

  1. issueから優先度が高そうなものを拾って着手
  2. ローカルでブランチを生やし、コミットログの頭にとりあえずwipとつけてcommit & push
  3. new pull request
  4. PRのページにtodoチェックリストを雑に書いて、それぞれをタイトルにしてissueを立てる
  5. issue番号をつけてcommitするとissueページに関連コミットが紐づけられるのでうまあじ
  6. todoを全部倒したらmerge & delete!

今回は先に立てていたissueが雑すぎて細かいタスクが多くなってしまったが、手順4をやることで作業のボリューム感が(他の人にも)わかるので良いと思う。実際にやってみて気づくこともあるだろうし。

普通はmerge前に誰かにレビューしてもらったりするのだろうからPRの単位は小さい方がいいのだろうと思う。この次はテスト書いてCIにつっこんでーみたいなところをやってみたい。

GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)

GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)

AndroidのIntent.ACTION_DATE_CHANGEDを受け取れない人へ

次のStack Overflowのやりとりが答えの全て。

stackoverflow.com

Intent.ACTION_DATE_CHANGEDはリファレンスによると日付が変わった時(つまり毎日0時0分)に飛んでくるブロードキャストインテントらしいのだが、時刻を求める処理にバグがあって、夜中ではなく正午に飛んでくることがある。

このインテントを発行しているのはAlarmManagerServiceという内部のクラス。端末起動時のインスタンスのセットアップで「次の日の0時」を計算してアラームをセットする。

問題の箇所は前述のStack Overflowの回答にもあるように、Calendarインスタンスを使って「今の時刻の時間と分と秒とミリ秒を0にして日付に1足す」ところで、時間を午前か午後の0時としてしまっているところ。このコードを注釈なしでどこが間違っているかパッとわかればおそらくJava初段くらいのウデマエと言ったところではないだろうか。僕は4級ぐらいなのでわからなかった。

public void scheduleDateChangedEvent() {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR, 0);   // !!! 正しくは Calendar.HOUR_OF_DAY とすべき
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.add(Calendar.DAY_OF_MONTH, 1);

    final WorkSource workSource = null; // Let system take blame for date change events.
    setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender,
    AlarmManager.FLAG_STANDALONE, workSource, null, Process.myUid());
}

つまり、端末を起動したのが午前中なら正しく夜の0時にインテントが飛んでくるはずだが、端末を起動したのが午後だとインテントは正午に飛んできてしまうということである。

Issue Trackerには2009年に報告されており、それからAndroid 6.0までずっと放置されている模様。

Issue 2880 - android - Intent. ACTION_DATE_CHANGED does not fire when the date changes. - Android Open Source Project - Issue Tracker - Google Project Hosting

どうしても日付が変わった時に何かしたいときは、 Intent.ACTION_DATE_CHANGEDを受けた時に正午だったら12時間後にオリジナルなインテントを発行するアラームをセットするなどの対策が必要。


「深夜0時に何か起きててアプリが動かない」というような相談を受けていろいろ調べた時に見つけたネタ。ちなみに相談とは全然関係なかった。