アナログ金木犀

つれづれなるまままにつれづれする

SHIROBAKOへの感謝と冒頭の高校時代のシーンについて

前置き

こんにちは、kgmyshinです。

今年もSHIROBAKO Advent Calendar始まりましたね。 頑張って書いていきたいと思います。

SHIROBAKOが放映されていたのは2014年10月から2015年3月までです。 当時放映されてた時は毎週楽しみに視聴し、次の回まで @konifar さんと話したりして、次の回よ早く来てくれと悶えてました。 また放映終了後は劇中に出てくる居酒屋柗亭に @konifar さん、 @shanonim、 @red_fat_darumaの4人で月一で足しげく通うこと4年目。 月日が経つのは早いものです。

変な話、SHIROBAKOに出会って以降、昇格したり、年収は上がったり、転職できたり、宝くじ1に当たったりしました。 自分ではありませんが、恋人ができた人もいます。 流石に宝くじは因果関係は無いかもしれませんが、それ以外のことについては正直全く因果関係がないとは言い切れません。 というのも、前述通りSHIROBAKOきっかけに柗亭に通うようになったのですが、 柗亭は自分にとって技術的な話、人間関係の相談、恋愛相談から愚痴まで様々なことを話しては切磋琢磨する場となっていたように思います。 悩んでるときにSHIROBAKOのとあるシーンが浮かぶことが多くありました。

「平岡みたいなやつ、どう扱えばいいんだよ...」

「こういう時に太郎がいれば...!」

「宮森の素直さ見習っていこうな」

「やっぱり杉江さんはかっけぇ、、、ああいう大人になりたい」

「ナベPみたいに飄々としたい」

「絵麻可愛い」

自分という人間を作っているものの小さく無いところをSHIROBAKOが、またそれをきっかけに得たものが占めており、それが諸々いい結果につながった可能性もあるのです。

ありがとう、SHIROBAKO。劇場版本当に楽しみにしてるし、これからもよろしくな。

それにしても劇場版どうなるんでしょうね。設定資料集にプロデューサの川瀬さんと堀越さんへのインタビューにこういうやりとりを見つけたのでちょっと抜粋して見ます(結構端折ってます)。

-- 続編の可能性は?

川瀬 「ないんじゃないかな?(笑)」

堀越 「あおいがあれ以上成長してしまうとさらに地味になり、少し生臭い部分にも触れてしまう。」

川瀬 「個人的に考えたことですが、やるとしたら、、、「第三飛行少女隊」がヒットして、劇場の話がでる。途端ナベPが倒れてしまう。プロデューサー代理として彼女が七転八倒しながら劇場版を作る、みたいな話ですね。」

川瀬 「劇場版で劇場版を作るというのは、ちょっと面白いいかなと思います。」

はてさて、川瀬さんの4年越しの思いは届くのでしょうか。ちなみにこの設定資料集の次の水島監督のインタビューにある下記は実現しましたね。

水島 「イベントをやるというのはどうでしょう?ステージをつくって「SHIROBAKO音頭」というのは?」

前置きが長くなってしまったので、本編は軽めにしたいと思います。

冒頭の高校時代のシーンについて

第一話の冒頭4分10秒の話です。

f:id:kgmyshin:20181201235420j:plain

(ちなみにこの絵麻のめずらしく眉毛がつり上がってる表情めちゃくちゃ可愛くないですか?全編通して二番目に好きです)

この約4分間をサマるとこうでしょうか。

メインキャラクター5人がアニメーション同好会で文化祭に向けてアニメ「神仏混淆 七福神」を制作。 文化祭は無事成功し、あおい達の卒業時に5人で東京でアニメ制作することを誓う。

ちなみに、このプロローグは「どんどんドーナツどーんと行こう(アニメ作るぞの意)」からシーンが始まり、「どんどんドーナツどーんと行こう(将来一緒にアニメ作るぞの意)」で終わります。そして「二年半後...」と本編に入っていきます。

この約4分間は本当に重要で、これによって視聴者は 5人は一緒にアニメを作ることができるのか!? と考えるようになり、すんなりと物語本編に入っていくことができます。

またそれだけでなく、ここではいろんなフラグや設定も散りばめられてます。

ズカちゃんフラグ

しずか 「声優志望なんてもんの凄い倍率だしさ〜」

という一言ですが、そのままリアルに身に沁みることとなります。

f:id:kgmyshin:20181201235731j:plain

はい。

「描け」

想像ですが、時にはネガティブだけどもコツコツとストイックにこなす絵麻が飾ったのかなと思います。

f:id:kgmyshin:20181201020427p:plain

設定資料集だと左下に名前かハンコみたいなものがあったのですが、アニメではないですね。 勝手に絵麻だと決めつけてますが、絵麻らしさが出てていいですね。

絵麻と親

絵麻の親がアニメーターへの道を認めてくれないというシーン、そして口では言えないから手紙で伝えたらとうとう条件付きで許してくれたというシーンもありました。 下記の記事でも触れたので深くは触れませんが、後々の布石としてなくてはならない大事なシーンです。

この約4分間をしっかり物語にした漫画あるのですが、絵麻と親についてはこの漫画でもう少し詳細に描かれていました。

最後に

最後に約4分間、本当に無駄なシーン一つないのですが、一個だけ「ん?そういえば、このシーンいる?」というのを紹介して、この記事の締めとしたいと思います。 夏にみんなで作業しているシーンです。

あおい 「へぇ、今日東京36度だって〜」

りー  「こっちはまだましっすかー」

しずか 「絶対、向こう行ったら、エアコンのある家に住もうね、絵麻!」

(自分)「(なんで突然絵麻にふった?)」

...エアコン...?

...

...

そういうフラグやめて!!!!!!2

これに関しては、フラグを立てたズカちゃんに少しオコです。

現場からは以上です。


  1. なんとなく買ったスクラッチで数万円あたりました

  2. 絵麻の部屋は4畳半トイレ風呂なしと言われており、エアコンもありません。設定資料集を見てもエアコンは確実にありません。

技術書典5にサークル参加します!

技術書典5とは

2018年10月8日(月)に開催される、技術書オンリーの一大イベントです!

techbookfest.org

サークル参加します!

前回の技術書典4は個人サークルの KUGIBAKO として参加しました。 今回は、個人サークルのKUGIBAKO に加えて、会社の有志を集めた 六本木一丁目で働いてます の一メンバーとしても参加します!

それぞれ、スペースは KUGIBAKOが え03 、六本木一丁目で働いてます が き09 となっております。

f:id:kgmyshin:20181004184004p:plain

技術書典に参戦される方はぜひ弊ブースにお立ち寄りください! 自分は基本的には個人ブースの え03 の方にいます。

本の紹介

【新刊: KUGIBAKO】 Ride on Jetpack

Android Architecture Components や Android Jetpack について、たとえば LiveData につい て深く説明したもの、ViewModel について深く説明したものなどは、今までにも多くありました。 自分も Jetpack HandbookNavigation について書いたりもしてきました。 しかし、それらを実際にどう組み合わせて使うかについて触れたものは、あまり出回ってないようです。 本書の目的はまさにそこで、LiveData、ViewModel などをどう組み合わせて使っていくかの 一例を知ってもらうための一冊となっております。

triokini.com

(上記リンクから取り置きができます)

【既刊: KUGIBAKO】 大きめなAndroidアプリでの設計を考えてみる

前回の技術書典4で販売した本です。(typoなどの修正をして、中綴じから平綴じになりました)

大規模なアプリのリードエンジニアを勤めてきました。大規模なアプリを作る場合、小さなアプリを作る上で考えなくてもよかった様々なことを考えなくてはなりません。

例えばの話をします。数冊の本から好きなものを取り出したい時、その数冊のレイアウト(どう並べるか?)に気を使う必要はありません。そこらへんに適当に積み上げておけばいいでしょう。
しかし、何千何万と冊数がある場合はそうはいきません。
そこには秩序立てた何かが必要です。カテゴリのラベルを貼った本棚、さらに粒度の細かいカテゴリによってしきりで分けて、本はタイトル順に。
また小説のカテゴリだけは出版社で分けて、タイトルではなく著者名であいうえお順に、といったようにです。

大規模で複雑なアプリを様々なチームメンバー達で開発して行く上でも、そういった秩序立てた何かが必要です。
本書では筆者が今まで構築しては運用し、例外にぶち当たっては再構築して来た秩序立てた何かすなわち設計や設計手法を紹介します。

「まえがき」より

triokini.com

【新刊: 六本木一丁目で働いてます。】 六本木一丁目で働いてます。

六本木一丁目にあるDMM.comという会社で働く有志で集まり、実際の実務から学んだチーム開発についてやAndroid開発、Redash、Vue.jsのコンポーネント、キーボードまで、ハードウェアから実際のコードまで色々と話しています。

自分はチーム開発のエモいことを書きました。自分の思うリードエンジニアのあるべき姿ってこんなんだよね?みたいなのを勢いで書いてます。今読み直したら恥ずかしいです。 個人的にオススメは「漢のセパレートキーボード入門」です。 通常のキーボードを買って真っ二つに割るところから始まります。技術的にも面白く、また普通に読み物としてもとても面白かったです。

(自分が表紙や裏表紙を率先して話を進めたのもあって、裏表紙に自分の趣味というかKUGIBAKOの表紙にでてくるおんなのk、うわなにをするやめr)

triokini.com

当日お待ちしております!

もし興味を持たれた方は、 https://techbookfest.org/event/tbf05/circle/25700003 こちらから「サークルをチェックリストに追加する」をポチッと押してくださませ!

10/8 技術書典5会場の え03 にてお会いしましょう!

ハナマサが足りない

仕事をしていて、煮詰まった時や集中できないときによく散歩をする。

足を動かすとアイデアが出てくることがよくある。それを狙ってるのが半分、ただそれだけでなく、リフレッシュしたいというのが半分ある。

この後ろ半分のリフレッシュ、これが本当に難しい。 経験則によるものだけど、リフレッシュするには、その時に抱えてる仕事や悩みを全く考えないくらい他のことに夢中になる必要がある、と思う。加えて、それだけでは足りず「楽しい」「癒やされる」などのプラスな感情も伴わなければならないというのも見過ごしてはいけない必須条件だ。

そう考えると、散歩だけでリフレッシュするというのは結構難しい。見慣れない場所での散歩ならば、些細な発見に冒険心をくすぐられることもあるだろう。だけども、僕らが散歩するのは日々の通勤で見慣れた道だ。散歩コースに新しい発見があることは少ないだろう。

一人で、それも見知った土地で行う散歩は内向的になりやすい。考え事をしやすいともいうが、考え事をしていてはリフレッシュにはならない。僕らは煮詰まったものを、そのまま煮詰めながら歩いてしまう。それ故に散歩によるリフレッシュは難しい。

だが、しかし、である。

実はこれを簡単に解決する方法がある。 そう、それが肉のハナマサだ。

散歩コースの前半に、「ハナマサに寄る」というのを追加するだけ。それだけで僕らは難解だったリフレッシュを体験することができる。(僕はハナマサが好きだけど、もし近場にハナマサがないのなら他の業務スーパーIKEAでも代替できるかもしれない。保証はしない。)

ハナマサは素晴らしい。 なぜなら、デカイ肉があるから。これを見るだけで、僕らの脳は心を踊らせる。 デカイ肉だけでなくて、デカイ魚もあるし、それ以外のなんかすごくデカイ何かがたくさんある。

これを体験するだけで、煮詰まってたはずの思考は、肉や魚やお菓子一色になること間違いなしである。そして、なんか適当にデカイ肉を買ったり、なんかデカイお菓子を買うことで、一層残りの散歩コースはその余韻を楽しむことができる。

今日はこのでかい牛肉をローストビーフにしてやろうか。久しぶりにanovaっちゃうかな? 豚バラブロックを買ったならば、ベーコンにしてやろうかこのやろう!などと考えながら歩くわけである。楽しくないわけがない。

そうやって仕事に戻ったときには完全にリフレッシュされ、なんならこのコードもいい感じには燻してやろうかこのやろう!とよく分からないハイテンションに仕事ができるわけである。

そう、ハナマサは素晴らしい。

いま僕に難点があるとしたら、転職した今の会社の近くにハナマサがないことだ。あぁハナマサが恋しい。ハナマサが近くにある会社に努めてるあなたが羨ましい。

【android】まれにレビューで指摘するParcelableについて

時差ボケからの早起きになってしまい、朝の時間に余裕ができたので小ネタを書いてみます。

Parcelableに関する全く同じ指摘をいくつかのプロジェクトでやってきました。

自分が見てきたプロジェクトでは、下記の条件を満たす場合はほぼ100%の確率で1回以上指摘しています。

  • kotlinを使っている
  • Parcelableをライブラリとか使わずに自分らで頑張ってる

この記事の結論はライブラリ使えってことではなく、ここを気をつけようって話になります。

テストには出ないエクササイズ

data class TestData(
        val num: Int,
        val str: String = "test"
) : Parcelable {

    constructor(source: Parcel) : this(
            source.readInt() + source.readInt() // ← ここ注目
    )

    override fun describeContents() = 0

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        writeInt(num)
        writeString(str)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<TestData> = object : Parcelable.Creator<TestData> {
            override fun createFromParcel(source: Parcel): TestData = TestData(source)
            override fun newArray(size: Int): Array<TestData?> = arrayOfNulls(size)
        }
    }
}

こんなクラスがあるとします。 ここ注目 という箇所に注目ください。

この時に TestData(4, "hi")インスタンスを作りIntentにputして遷移先でgetした時、numstrの値はどうなるでしょうか??

プロダクションコードでこんなのを書いてきたら困惑ものですが、遊びと思って考えてくださいませ。

ちなみに、ここで「なーんだ」とわかる人はこの先を読む必要がありません。

回答は最後にします。

よく指摘するケース

さて上記の回答&解説をする前に、よく指摘するケースも見ておきます。

data class TestData(
        val num1: Int?,
        val num2: Int?,
        val str: String
) : Parcelable {

    constructor(source: Parcel) : this(
            source.readInt(),
            source.readInt(),
            source.readString()
    )

    override fun describeContents() = 0

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        num1?.let { writeInt(it) }
        num2?.let { writeInt(it) }
        writeString(str)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<TestData> = object : Parcelable.Creator<TestData> {
            override fun createFromParcel(source: Parcel): TestData = TestData(source)
            override fun newArray(size: Int): Array<TestData?> = arrayOfNulls(size)
        }
    }
}

このコードには致命的な問題があります。わかりますでしょうか?

java.lang.IllegalStateException が発生したりします。

解説

イメージの話です。Parcel には直列的に値が積まれていきます。

TestData(1, 2, "aaa") の時、 Parcel には 1, 2, 3, a, a, a という風に値が積まれていきます。 3 は文字列のlengthですね。

この Parcel から取得する時も直列的に取得していきます。

  1. 1回目のreadInt()num11 が入る
  2. 2回目の readInt()num22が入る。
  3. readString() で 初めの3, a, a, a を取得。サイズを取得してその後ろのサイズ分getする感じです。これが str に入る。

この場合はちゃんと動きますね。

では TestData(null, 2, "aaa") の時を考えましょう。

        num1?.let { writeInt(it) }
        num2?.let { writeInt(it) }
        writeString(str)

となっているので、初回の writeIntは走りません。そのため Parcel には 2, 3, a, a, a という値が積まれます。

これをgetするとどうなるでしょうか?

  1. 1回目の readInt()num12 が入る。(ここですでに間違ってますね)
  2. 2回目の readInt()num23 が入る。 (これも正しくない)
  3. 3回目の readString() 時にサイズが取れず、 IllegalExceptionが発生する (😇)

こうなります。ダメダメです。

では、これを修正してます。

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        writeInt(num1 ?: 0)
        writeInt(num2 ?: 0)
        writeString(str)
    }

で、いいじゃんと思う方がいるかもしれませんが、これも厳密には間違っています。 TestData(null, null, "aaa")TestData(0, 0, "aaa") となってしまうからです。

修正方法は単純でnullかどうかのフラグもParcelに詰めてやります。(他にやり方あったら教えてください)

:
    constructor(source: Parcel) : this(
            if (source.readInt() == 1) source.readInt() else null,
            if (source.readInt() == 1) source.readInt() else null,
            source.readString()
    )

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        writeInt(if (num1 != null) 1 else 0)
        if (num1 != null) {
            writeInt(num1)
        }
        writeInt(if (num2 != null) 1 else 0)
        if (num2 != null) {
            writeInt(num2)
        }
        writeString(str)
    }
:

こうすることで取得する時に対象がずれることがなくなります。

一件落着。

"テストには出ないエクササイズ" の回答&解説

回答は num=6, str="test" となります。

ここまでくれば解説もいらないと思います。

TestData(4, "hi") となっている時、 4, 2, h, i と積まれています。

data class TestData(
        val num: Int,
        val str: String = "test"
) : Parcelable {

    constructor(source: Parcel) : this(
            source.readInt() + source.readInt() // ← ここ注目
    )
   :
}

pos=0の4 と pos=1の2を足したものが numstr はデフォルト値となるので、TestData(4+2, "test") となるわけです。

結論

自分でParcelableを実装する時は値が積まれていくのをイメージすべし!

ちなみに、javaのときは int はプリミティブで null になることはなかったし、 Integer 使ってたとしてもその場合は writeValue / readValue(class loader) 使えば null 時もいい感じに動くので、こういうミスに遭遇する人は少なかったんでしょうね。

追記

修正コードについて、Int? に関しては writeValue を使うことでも問題なく動きます!なので、この方法でも良いです。

ただ個人的には、雑にやってるとランタイムにjava.lang.RuntimeException: Parcel: unable to marshal value で落ちるのでなるべく使わないほうがいいのかなという考えです。

くろかわさんから質問いただきました!

酒の席では思い出せなかった回答。

androidエンジニアとしてgoogle io2018での気になるところまとめ、あるいは帰ってからの宿題

帰ったらしっかり調べて会社ブログなどに書くとして、ひとまず雑に気になるところをまとめてみた。 何かしら一言コメントしてるところありますが、基本的に正しい保証ないです。

jet pack

ざざっとみる限り、指針やライブラリ群などまとめた物を総称してJetPackと呼んでいる?? とあるセッションでは下記のように説明されていた

  • guidance
  • recommended libraries and tools
  • has a cute logo

下記はdeveloper page

地味に、下記のようにさらっと書かれている。

The UI will consist of a fragment UserProfileFragment.java and its corresponding layout file user_profile_layout.xml

fragment_user_profileじゃないんですね、うぃす。

f:id:kgmyshin:20180510062359j:plain

Navigationまわり

developer page

navigation editorの話

migrate to the navigation arch componentとか読んでみるとといいかも

codelabのURL

Constraint Layout2.0まわり

ここのアニメーションのやつ。そもそもConstraint layoutのくだりだったか覚えてない

タイムラインで座標与えてアニメーションを作れたりするみたい。どういう感じでxmlに落ちるんだろうか?

セッションではMotionLayoutといってConstraintLayoutのサブクラスとのこと。 Motion Editorの動きは下から!

youtu.be

上記リンクはMotionEditorから再生になるけど、必見オブ必見なのでみてみるといいと思います。

app bundle

dynamic feature moduleごとにダイナミックにダウンロードできて、初回のapkのダウンロードサイズを減らすという話な認識。

もろもろ分割されるタイミングとか条件や、仕組みをしっかり知りたい。

今井さんがまとめてくれてるのがわかりやすい。

Android App Bundle/Dynamic feature modulesにみるモジュール化の未来 - tomoima525's blog

テストどうすんねんって今井さんと話してたんですが、ちょうど tnjさんが聞いてくれてたみたいでした!

work manager

あんまりまだ話に出てきてないけど新しいAPI

codelabはこっち

material components

githubのURL

toolsとか時間ある時に眺める

あと、普通にライブラリがあるらしく、 UIやStyleが用意されているみたい。

その説明をしているところが下記。

youtu.be

Slices

new approach for remote content.

  • templated
  • interactive
  • updatable

19+以上で使えるらしい。

jet pack並みに気になってるところ。

実装方法はdeveloperページに載ってる。 google searchとかに表示させる実装方法はセッションで言ってたけど早くて追いつけなかった。 動画が公開されたら見直す。(下記の動画)

Android Slices: build interactive results for Google Search (Google I/O '18) - YouTube

その他の気になるcodelabs

見直すセッション、見れなかったけどあとで見るセッション