@numa08 猫耳帽子の女の子

明日目が覚めたら俺達の業界が夢のような世界になっているとイイナ。

Elastic Leadership を読んだ

エラスティックリーダーシップ ―自己組織化チームの育て方

エラスティックリーダーシップ ―自己組織化チームの育て方

2018年の Droidkaigi の中でこの本が紹介されていたので、会社の経費でポチってもらった。回し読みをしてようやく順番が回ってきた。

numa08.hateblo.jp

感想

チームが今ある状態を「サバイバルフェーズ」「学習フェーズ」「自己組織化フェーズ」に分割し、リーダーはチームを自己組織化フェーズへと導くことが仕事であるとしているのが著者の主張だと感じた。これに関して自分はたしかにそのとおりだと感じた。思えば、自分は小さな組織でリーダー的なポジションになることが多かった。例えば高校の部活動、例えば大学のサークル、例えばバイトetc...

どんなチームであっても思うのは、メンバーに勝手にやってほしいと思うことだった。今にして思えば、それは自己組織化フェーズへと進化したチームのことだったのだろう。そしてこれは、大体のリーダーが考えていることだと思う。よく言う「経営者的思考を身に着けてください」と経営者が言うアレだと思う。

チームのメンバーはチームリーダーが自己組織化されたチームを目指していても、メンバー自体はそこまでの給料をもらっていない事を考えるとモチベーションは普通の状態では持ち合わせない。チームリーダーの仕事で難しい部分は、自己組織化されたチームの状態がどういうもので、なぜそれを目指すのかをチームメンバーで共有するところかもしれないと感じた。

自分たちのチームはどんなチームだろうか

この本を読んで、自分たちのチームがどんなチームなのかを振り返ってみたいと思う。実は、今のチーム(コベリン)は会社全体をチームとして見たときにまだサバイバルフェーズのままなのかなと感じている。と言うのも、案件に関するノウハウの共有もできていない部分も多く(バス因子)、スケジュールがカツカツと言うわけではないが、組織で体系的に学習ができているわけでもない。

例えば、デザインであれば今のところ社長がほぼ1人でこなしている。これはバス因子だろう。こういったノウハウやスキルを他のメンバーがみんな学習し始めることで初めて学習フェーズへの移行ができていると言えるのではないだろうか。バス因子のリストアップをするだけでも良いかもしれない。学習フェーズでは生産性が落ちるだろうが、それは仕方のないことなんだろう。

小手先のタスクリストという意味であれば、あとはコミットメント言語をしっかりと使っていくことだろうか。本を読んで感心したのは「バグを明日までに取り除きます」という発言は、約束できる言葉では無いと批判していたこと。ソフトウェアのエンジニアならだいたい今日考えられると思うけれど、バグは大体の場合自分が思っているよりも広範囲に影響を与える物だったり、修正自体は簡単だけれど調査がめちゃくちゃ大変なものが多い。つまり、こう言った場合に利用するコミットメント言語は「少なくとも、1日に5時間はバグの調査を行います。そのために、他のタスクを止められるように調整します」と言うことだ。確かに、そのとおりだなと思った。リーダーがサポートする部分は、コミットメント言語を得ること、そしてそれを実現するためにサポートすることなのだろう。

こうやってこの本を読んで自分のチームを見直すと色々と不十分な部分が目立つ。もちろん、ある側面ではできている部分もあるだろうが、ある側面ではできていない部分もあるのだろう。学習フェーズとサバイバルフェーズの中間くらいにはいるかもしれないが、自己組織化フェーズには至っていないと言ったところだろうか。

DJI Tello のビデオストリーム iOS でデコードする

できあがったものがこちら

github.com

4月の終わりにDJIから発売されたトイドローン、Tello。発売と同時に購入したけど、前評判通りに高い安定性を発揮してくる上、風がなければ屋外でも遊べるので、今までとは違うアングルからの写真撮影が楽しめて面白い。

そんな Tello は今のところスマホWifiで接続をして操作することしかできない。この値段帯のトイドローンならだいたいプロポが付いて来るんだけど、そういうのを削って本体のコストにしたってことなのかな?

あと、一応UDPで通信をするAPIもあるのだけれど、純正アプリと同じことはできない。純正アプリではカメラの画像をリアルタイムにプレビューできるし、前後左右上下の操作以外にもフリップや360度回転、手のひら着地なんかのコマンドを実行できる。一方で公開されているAPIは前後左右上下の操作を行うことしかできない。

そういった部分に不満を覚えつつ、夜な夜なパケットキャプチャしたデータを眺めていたら、すでに同じようなことをしていた人が海外にはいたらしい。go言語で書かれたiot用ライブラリのgobotにtelloの隠しインターフェースが追加されて公開されていた。

Hello, Tello - Hacking Drones With Go

日本版が出る前に公開されたエントリーなので、最初にこのブログをみつければパケットを開くこともなかっただろうな。

このエントリーのサンプルコードを実行するだけで、 mplayer を利用して動画のプレビューをPCから行うことができる。さらに、動画の仕様に関しては次のように書かれていた。

The streaming video is also sent to the ground station on a different UDP port. Unfortunately the Tello does not just use one of the existing standards for streaming video such as RTSP. Instead, the raw video packets are sent via UDP and need to be reassembled and decoded before they can be viewed.

Since the size of a single video frame is larger than the size of a single UDP packet, the Tello breaks apart each frame, and sends the packets with header of 2 bytes to indicate how they need to be reassembled.

Position Usage 0 Sequence number 1 Sub-sequence number 2-n Video data The video data itself is just H264 encoded YUV420p. Using this information, it is possible to decode the video using standard tools such as ffmpeg, once you remove the header bytes.

H264でエンコードされたYUV420pのピクセルデータだけど、いわゆる動画配信用のプロトコルには則っていなくて、生のバイナリをUDPで送っているので適当にデコードする必要があるよ!!って感じ。

H264でエンコードされた動画だったら、ffmpeg + lib264 とかでデコードできそうだなと思ったので、iOS 上でやってみることにした。

コード解説

ffmpeg や libx264 のビルドはすでにビルド用のスクリプトを作ってくれた人がいたので、それを利用した。

github.com

github.com

実際に動画のフレームをデコードする実装の抜粋が以下。

gistb93addb5b78d3a6417df2e7d77412655

コードの全体はこちら

Turkey/ImageDecoder.mm at 430f060486b902ee0f9178b4dc20bdc7de2242e8 · numa08/Turkey · GitHub

ffmpeg にバイナリを与える

利用しているのは ffmpeg , libx264 、そしてさっきの gobot を iOS 用にラップしたライブラリ。gobot は tello が送ってくる動画のバイナリをコールバックで渡してくるので、バイナリを処理する必要がある。アプリ側はバイナリを得ることはできるのだけれど、どうやらffmpegのインターフェースを利用する場合、直接バイナリを渡すには AVIOContext インスタンスを作って、コールバックを利用してバイナリを返す必要があるのだけれど、ちょっと考えることが多くて面倒くさい。

そこで、 NSPipe というAPIを利用することにした。

NSPipe - Foundation | Apple Developer Documentation

Linuxpipe(8)をラップしたAPIで、 pipe の作成、そして書き込みと読み込み用の file descriptor を作ってくれる。また、linux は pipe を作ると pipe:<file descriptor> というファイル名でアクセスをすることができるようになる(これの仕様ってどこに書かれてるんだ?)。この仕組みを利用することにした。

init[NSPipe pipe] を使って NSPipeインスタンスを生成する。 Tello と通信を行い動画のバイナリを取得する onNewFrame: では [self.fifoPipe.fileHandleForWriting writeData:packet]; を行うことで動画のフレームを書き込んでいる。 ffmpeg を利用する captureInFFMpeg では

int fileDescriptor = self.fifoPipe.fileHandleForReading.fileDescriptor;
const char* file = [NSString stringWithFormat:@"pipe:%d", fileDescriptor].UTF8String;
// 中略
ret = avformat_open_input(&format_context, file, input_format, &format_dictionary);

として pipe:<file descriptor> というパスのファイルをパラメータにして ffmpeg に与えている。こうすることでファイルの入力なら簡単にできる ffmpeg にファイルに見せかけたバイナリを渡す仕組みを実現することができた。

正しいバイナリを作る

Tello から取得したバイナリを ffmpeg に与えることができたのであとは ffmpegAPIを使ってデコーダーを実装していく。これはそんなに面白くないので割愛。

しかし、実は Tello から送られてくるバイナリは厳密には動画の生のバイナリではない。実は1つのフレームのバイナリを8個の送信に分割して送ってくる。今回、アプリを作り始めるまで知らなかったのだけれど udp は送信容量に上限がある。

UDPパケットサイズと転送レートの関係:プログラマー社長のブログ:オルタナティブ・ブログ

Ethernetフレームは最大サイズが1518バイトですので、そこから、Ethernetヘッダ(14バイト)とFCS(4バイト)を除いた、1500バイトが送出できる最大サイズになります。IPv4UDPを送出するには、IPv4ヘッダ(20バイト以上)とUDPヘッダ(8バイト)を除き、1472バイト以下がデータサイズになります。

今まで心を無にしてHTTPを触ってきたので、こんな仕様があることを知らなかった。動画のバイナリは 1472 バイトを余裕で超えるので、分割されるというわけ。どうやら8個のパケットに分割されているようなので、8という数字を決め打ちにしてしまって実装を進めることにした。

動画のフレームを受け取るonNewFrame: で、8個分の NSDayaNSArray を作り、マージして書き込みを行う。

[self.packetArray addObject:frame];
if (self.packetArray.count == 8) {
  NSMutableData *packet = [NSMutableData data];
  for (NSData *d in self.packetArray) {
    [packet appendData:d];
  }
[self.fifoPipe.fileHandleForWriting writeData:packet];
self.packetArray = [NSMutableArray array];
}

先頭に正しい動画のフレームを挿入する

ここまで実装をしてどうにか iPhone の画面上に Tello の動画をプレビューすることができた。

そのしばらく後

コードを全く変えていないのに h264 がデコードに失敗するようになった。なんで??なんで??

どうやら、先頭のフレームに含まれているヘッダー情報を正しく読み込むことができなくて失敗しているように思えたので、じゃあ正しい情報を与えてやればいけるのでは・・・?と思い実装。

PCで取得をした Tello の動画のフレームの先頭をプロジェクトに加えて、Telloが動画フレームを返すより前に ffmpeg に渡してやることにした。コードではopenのあたり。

// 正しいフレーム情報をもった動画ファイルを読み込んで、
// avformat_find_stream_info を成功させる
dispatch_async(writeFifoQueue, ^{
        NSString *p = [[NSBundle mainBundle] pathForResource:@"movie" ofType:@"mov"];
        FILE *i_file = fopen(p.UTF8String, "r");
        if (i_file == NULL) {
            NSLog(@"failed fopen");
            return;
        }
        int buffer_size = 10 * 1024;
        char buff[buffer_size];
        size_t size;
        while (true) {
            size = fread(buff, buffer_size, 1, i_file);
            if (size == 0) {
                break;
            }
            write(self.fifoPipe.fileHandleForWriting.fileDescriptor, buff, buffer_size);
        }
});

ちょっとパワーの有る方法だったけどこれで確実に成功するようになった。めでたい!!ちゃんとgcdを利用していたので、変なブロック処理やwaitを挟む必要が無いのも偉い。

感想

iOSシステムコールって読んで良いんだ・・・?

最近、LinuxシステムコールAPIに関する本を読んで勉強し直したところだったのでちゃんと役立てられて嬉しい。

numa08.hateblo.jp

C言語最高!!これで行きていける!!!みたいなことを考えることもなく、それでもswiftとかkotlinとかレイヤーの高いところで生きていきたいのだけれど、とは言え触ることができるっていうのは良いことだと思う。

あと、go言語で書かれたライブラリを利用できたのも良かった。個人的にgo言語は好きな言語で、CLIのツールを作ってgithubのスターを稼いだこともあったけど、しばらくご無沙汰だったため、久しぶりに利用できたことが素直に嬉しい。はじめ、gobotのtello関連のモジュールだけをswiftに移植しようかと考えていたけど、流石に面倒だったのでやめた。gomobile を利用することでiOSAndroid向けのアプリやライブラリをビルドすることができることは知っていたけど試したことはなかったので、良い挑戦だった。と言っても、gobotが依存しているライブラリも少ないためか、特に何もしなくてもそのまま素直にビルドをすることができた。時代はgo言語って感じ。

今後

この手順で最終的に UIImage インスタンスを取得することができたので、例えば Vision framework なんかを利用して自動操縦の自撮りドローンなんかを実装できそうだなーって考えている。

ふつうのLinuxプログラミング 第2版 を読んだ

今年の頭からLinuxAPIシステムコール、libcなんかについてちゃんと勉強をしようという気持ちになったので、それ関連の本を読んでた。

numa08.hateblo.jp

前回読んだ「[試して理解] Linuxのしくみ」という本も良い本で、LinuxというOSがどういう仕組で動いているのかという触りを理解するためにかなり役立った。そこから一歩踏み込んで、ちゃんとLinuxシステムコールやlibcのAPIを使えるようになりたいと思ったので、次の本を読んだ。

実は、第1版が家にあったんだけど(たぶん、奥さんが買った)、利用しているOSにFedora Coreとあったので、内容が古いなと感じたため第2版を購入した。久しぶりにこういう本を読みながら写経をしていたのだけど、やっぱり紙の本が良いなと思ってしまった。

初めてやってみるのにはちょうどいい構成の本だった

あんまりLinuxの基本的な仕組みについては詳しくない自分でも読み進めることができる内容だった。本の構成としてはシステムコールAPIの解説の後に headcat と言ったコマンドを模したプログラムを作る例題がある。そのあとで、少しレベルの上がった練習問題が掲載されている。練習問題の解答はサポートサイトにある。

練習問題の内容は本の内容から見るとちょっと難しいので、自分の理解度に応じて挑戦をしてみるのが良いと思った。実際、自分もちょっと後回しにして本を読むことを優先していった。ただ、最初の方で man コマンドの利用方法や読み方の解説があるので自分で関連するAPIを調べながら進めることができた。

練習問題の内容は多少レベルが高いかもしれないけれど、例題や解説の書き方は非常に親切で分かりやすかった。manページは情報が全て書かれているけど、その分、文章が分かりにくくかったりするので、本の内容を読んでからmanを見ると「あ〜なるほど〜」ってなる。

章の構成はストリームやファイルシステム、シグナルの取扱を一通り学んだあとで最終的にネットワークプログラミングへと進んでいく。ネットワークプログラミングと言っても、TCPのソケット通信を行うくらいでページとしては少ない。そして、最後に総仕上げのおさらいとして、HTTPサーバーの構築を行う。この組み合わせが面白かった。

HTTPサーバーは、ファイルシステム上のファイルの読み込みに加えて、シグナルの取扱やマルチプロセス、ソケット通信を行う必要があることから本の内容のおさらいとしてはぴったりの内容だと感じた。

また、この本を読む前に[試して理解]Linuxのしくみを読んでおくと、登場するAPIシステムコールが何を行っているものなのかという事前知識を持って挑むことができるので、ちょうど良かった。

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

この本を読んだあと

「詳解Unixプログラミング」のような分厚い本に手を出しても良いかもしれないと考えている。その一方で、ここまでで蓄えた知識を使って、なんかのアプリケーションを作ってもいいなーっとも思っている。戯れに、二酸化炭素濃度センサーを購入してみた。

ja.aliexpress.com

せっかく raspberry pi もあるので、 Linux の仕組みの上でこういったセンサー類を利用しやすくする何かを作っても良いかもしれない。

[試して理解]Linuxのしくみ を読んだ

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

普段使っているOS, Linux がどういう仕組みで成り立ち動作をしているのかをデバイスのレイヤーを含めて解説してくれている本。

以前、「Androidを支える技術I, II」を読んだときにLinuxに関する知識が全然足りてないなぁと感じたこともあって手に取った。

numa08.hateblo.jp

numa08.hateblo.jp

Androidを支える技術II」の後半では、アプリケーションのプロセス管理の仕組みを解説する章がある。その中では、Linuxのプロセス管理がどうなっているのかを解説した上で、Androidがどういうふうにその仕組をカスタマイズしたのかの解説が行われていた。この章を始めとして、「Androidを支える技術」の本の中では、AndroidがLinuxOSであるという仕組み上、Linuxの仕組みを知っておいたほうが理解が進むなと感じる章立てとなっていた。

自分はLinuxをわりと日常の中でもよく利用している。アプリケーションの運用こそは最近は行っていないけれど、1年前は業務の中でやっていた。他にもアプリケーションの開発環境をLinux上で行うことはよくあるし、今もやっている。その中で、よく発生するのが性能低下であったり、可用性の確保をしなければならないシーンだ。

アプリケーションの性能が低下したときに、一体何が起こっているのかをまずは解析しなければならない。幸い、Linuxには様々なOSの状態を表示するためのコマンドが揃っているが、それらが表示してくれる数字を理解するのはまだ人間の仕事だ。freeコマンドでメモリの使用量が出るが、様々な数字があって何を意味しているのかを知らなければならない。sarコマンドで様々な数字が出るが、一体この数字をどう読んで何をしなければならないのかを知っておかなければならない。

この本は、そう言ったアプリケーションの運用をする上でLinuxがどういう仕組でOSを動作させ、プロセスを実行し、デバイスを利用しているのかを丁寧に解説してくれる本だ。コマンドの利用方法ではなく、仕組みの解説を行うための本となっている。OSを動作させ、プロセスを実行し、システムコールを発行し処理して、デバイスにアクセスを行うことはそれだけでオーバーヘッドとなりシステムの性能低下を招く。従って、まずは仕組みを正しく理解しておくことで、どこでどういうオーバーヘッドが発生し、何を利用すればそれを発見することができるのかが分かる。発見ができたら次は対策だ。

この本は、更にサンプルコードを利用した実験もある。システムコールの発行やプロセスの実行、デバイスアクセスと言った動作を自分の書いたコードを使って実験し、観測することができる。言語としては主にC言語、ときどきPythonまたはシェルスクリプトと言った感じ。言語に関する詳しい解説はないので、一応C言語くらいは利用できる状態で読みたい本だ。

また、この本は良くも悪くも初心者向けの本だけれどLinuxを全く触ったことが無い場合にはしんどいかもしれない。基本的なファイル操作やエディタの操作、パッケージ管理ソフトの導入に関する部分については知っておいたほうが良さそう。そして、この本を読んでさらに次のレベルにステップアップをしたいと思える内容だった。

本の後ろの方に、次に読むべき本がいくつかリストアップされていたので手を出してみたい。

Linuxを使ってアプリケーションの開発や運用を行う上で、絶対に読んでおきたい本だった。

京都行った

大阪に引っ越しをして半年くらいが経過して、そう言えば以前から行きたかった京都鉄道博物館にまだ行っていないことを思い出したので行ってきた。

混むことは分かっていたので、平日を狙っていったけどそれでも入館は並ぶことになった。

ホテルが良かった

www.jalan.net

京都駅の南、徒歩5分くらいで九条の駅の手前くらいにあるホテルを今回は利用した。ここが思った以上に良かった。

内装や外装は落ち着きのある、都会的なおしゃれデザインに統一されていた。ロビー部分にはソファーはもちろん、焚き火を囲むことができるようになっていた。落ち着いた照明でリラックスできるし、しかも面積はそこまで無いけれど空まで吹き抜けになっていたので開放感があった。

宿泊者はウェルカムドリンクをサービスしてもらえるのもポイントが高い。焚き火を囲んでソファーに座り込んでハイボールを飲むと、それだけで一日の疲れが解消されていく。

お風呂上がりにはフリードリンクコーナーもあり、これもまた落ち着きのあるカフェのようなラウンジスペースでコーヒーやジュースを頂くことができた。眠り前にホッと一息をつくことができて、しっかりと休むことができたと思う。

部屋も適度に広くて清潔感のあるベッドだった。

これで、一人晩御飯抜きで6,500円だったのでかなりリーズナブル。費用対効果が最高のホテルだった。

晩御飯はリッチに決めた

ホテルの料金を抑えることができたし、今回は京都往復で交通費もそんなにかからない事を考えて、ちょっと良いものを食べようと計画していた。色々と案を出す中で上がったのが、三嶋亭のすき焼き。

www.mishima-tei.co.jp

名前は聞いたことがあったし、四条の方に遊びに行ったときに前を通ったことはあったけれど、実際に入ろうとは思ったことがなかった。でも、確実に美味しいだろうなと思ったので予約。

外食ですき焼きを食べることなんてあまりないし、外食の中でも今までにないくらいにリッチなやつなのでかなり期待をしていった。

これが、かなり最高。お肉や野菜は適量を焼いてもらえて食べるタイミングを完全にコントロールしてもらえる。最高のタイミングで食べることができた。そして、肉もでかくて分厚くてそれでいて美味しい。焼いてない状態で手のひらくらいの大きさのお肉だったけど、口に入れると柔らかくて溶けていくようだった。

これが、良い肉・・・

本命、京都鉄道博物館

先にホテルとか晩御飯のことを書いたのはこの部分の記事が長すぎるから。今回、京都旅行は1泊2日を予定していて、1日目は京都鉄道博物館に、2日目は適当に京都観光の予定だった。その予定だったのだけれども、京都鉄道博物館を回りきることができなくて2日目も鉄道博物館に行った。まさか、2日連続で行くことになるとは思わなかった。

博物館を回りきることができなくて2日連続で行くという自体が自分の中で初めてのことだったけれど、さらに2日連続で回っても回りきることができなくて、後日改めて行くことにした。

公式サイトによれば2時間くらいで回ることができると言うけれど、2日じゃ足りなかったのでかなり回り方が下手だったというか、スローペースだったと言うか。

そんなところだったけれど、その分充実した時間を過ごすことができた。

面白かったものの写真を幾つか掲載してみる。

例えば、0系新幹線の自動運転関連の装置。昔の写真で見る超大型の計算機って感じで興味深かった。運転台のところの壁の一面がこの計算機になっているのだけれど、これより前の世代の車両にはこんなものは無かったし、後の世代の車両にも無かった。後の世代の車両では、たぶん小型化に成功してもっと小さなものになったんだろうと思うけど、前の世代の車両ではそもそもこんな計算装置が無くて、いかに新幹線という乗り物が他の乗り物と一線を画する特別なものだったのかが分かるようだった。

他にも、昔から憧れたトワイライトエクスプレスが展示されている部分もあった。超高級列車として存在感があったけど、結局、一度も乗ることもなくその運行が終わってしまった。ブルートレインの全滅もあって、子供の時に寝台列車に乗れなかったことがただただ惜しいと思う。

あと、500系新幹線のエヴァコラボのものが展示されている。通常時は普通の500系新幹線になるのかな?絨毯の上に新幹線が置いてあるという状況が面白い。デザインの格好良さは圧倒的だよなぁ。

車両以外でも様々な展示があって、例えば通票閉塞機の実物なんかもあるし、しかもサイド部分が透明になっていて内部の構造を眺められるのが楽しい。この閉塞機は大宮の鉄道博物館とか大洗駅なんかにもあって何度も見たけれど、内部の構造が分かるものは無かった。

閉塞機の後ろには、実際の信号やポイントをコントロールできるシミュレーターもあって、正しく入力を行えばポイントを動かすことができる。

こういうものを全部見ていたら結局時間がなくなったので、2日目に持ち越した。

2日目で思ったことは、1日目に吸収をした知識の復習ができる環境が整っていること。入り口に展示されている0系新幹線蒸気機関車C61なんかのブレーキの構造や連結器の種類なんかを全て眺めながら見ていくことになったので、やっぱり時間が足りなかった。

2日間かけて館内は全部見たけれど扇形車庫を見るには至らなかった。

記憶も曖昧な年の頃、まだ梅小路蒸気機関車館だったころに扇形車庫は見たのだけれど今の年齢になって見るものとはまた違うんだろうなぁと思いを馳せた。

そんなわけで、まだ見足りないし、2日間かけて蓄えた知識もあるのでそれらの復習もかねて何度も何度も通いたいと思える場所だった。年間パス無いかなぁ・・・。

アルテミスを読んだ

アルテミス(上) (ハヤカワ文庫SF)

アルテミス(上) (ハヤカワ文庫SF)

アルテミス 下 (ハヤカワ文庫SF)

アルテミス 下 (ハヤカワ文庫SF)

近未来の月面を舞台に、密輸業を営む主人公の女性が不可解な依頼を受けたことをきっかけに、微妙な人間関係の人々と手を組んで月都市を巻き込む陰謀に立ち向かうストーリー。

物語の登場人物が多いのだけれど、その一人ひとりがストーリーの終盤に絡んでくる構成にワクワクした。

作者は火星の人と同じ、アンディ・ウィアー氏。火星の人のときもそうだったけれど、困難な状況に面していながらも明るい語り口と科学知識で課題を解決していく軽快なノリが楽しい作品だ。

主人公は溶接の技師でもあって、物語中に何度かこのテクニックが発揮されるシーンが登場する。月面という低重力、ほぼ真空空間中での溶接作業なんて今までの人生の中で全く想像したこともないようなテクニックを発揮する。この中でやはり作者の持つ化学の知識が発揮され、何が危ないのか、何が困難のか丁寧な解説が行われる。それでも、専門書のように小難しい内容になるのではなくテンポよくストーリーが進行していく。 主人公も魅力いっぱいだ。月面都市のアルテミスのアンダーグラウンドというか、そっち系に顔の効く彼女は誰からも愛されるタイプのキャラクターだ。関係が悪化しても殺したいほどの子ではない、いつまでたっても悪ガキのような少女のような。設定年齢よりも少し幼く感じた。あんまりリッチではないけれど、精一杯生きている感じ。そんな彼女だからこそ、街を誰よりも愛していて、それゆえに皆をまとめることができたんだろうな。

知らなかったけれど、この作品も映画化が決定しているらしい。楽しみ。

作者の構想としては、月面都市アルテミスを舞台とした別のストーリーを作っていく思いがあるらしい。次回作にも期待をしたい。

Androidを支える技術II を読んだ

組み込みOSでありつつもセキュリティアップデートやユーザがインストールするアプリケーションに対応しそれらをマルチタスクで実行し、さらにユーザのリテラシーはサーバーやPCと比べても低いであると想像される。それが、Androidに求められた要件。これを、一般的なPCやサーバーと比較して貧弱な携帯電話上に構築する必要があった。

自分が初めてAndroidのアプリ作りを経験したのは、2009年か2010年のことだったと思う。初めて本を買ってきて4つのコンポーネントを学び、コードを意味もわからず写経していたとき、なぜ画面単位をActivityと言うもので管理するのだろうか?と考えていた。それ以前にGUIのプログラミンををやったことがあるわけでもなかったので、「きっと頭の良い人が考えれば理解ができる点なんだろうな」と思って後回しにしていた。それから10年近く経った今の今まで深くその理由を考えることなく進んできた。

本書はActivityが生成されて画面に出るまで、そしてどういった条件下でActivityが破棄されるのかのプロセスをLinuxのレイヤーから順番に追いかける構成になっている。アプリのインストールが行われたらPackageManagerServiceがpackage.xmlを更新してIntentを解決できるようにし、端末がブートしたときに関連するサービス群を起動し、Activityをスタックで管理する仕組みの中にユーザが起動したActivityを含めていく・・・という流れになると言える。

更に、再生成におけるデータの保持を実現するためのBundleの仕組みについての解説もある。どうやってActivityのもつデータを一時的に保持しておくのか、再生成のときだけ復元するのかの仕組みをコードとともに紹介している。実は自分はBandleは一度ファイルI/Oが発生するものだと思っていたけど、そう言う訳ではないらしい。こう言った誤った知識が正しく訂正されるきっかけとなるのも嬉しい。

Androidソースコードに注目をした本は他にもあったと思うが、やはりこの本が別なのはLinux的部分ではなくてAndroid的な部分に重点を置いていること、そして話題とする部分を絞って解説してくれることで、注目するべきソースコードが何のかがわかりやすくなる構成にあると思う。この本で言えばActivityの起動に関するプロセスについてのみの話題で1冊が構成されている。手広くなって読者目線で何が起こっているのかわからなくなってしまう、ということが無いのだ。

Androidのアプリを開発する中で、Zygoteというプロセスを見かけることはよくある。スタックトレースを辿っていくと最後の方に現れるやつだ。あれが一体何なのかは雰囲気的にランループを作るところなのかな?くらいの認識だったけれど、その実態はアプリケーションの起動を司るめちゃくちゃ重要なシステムサービスの1つだ。今まで単語が出てきても深くは考えずスルーしていた部分についてしっかりと理解をすることで、今後のバク調査やアプリ開発でも役立つかもしれない。

この本を読んで学んだことの1つに、1つのアプリケーションは1つのプロセスになるとは限らないと言えることだと思う。Androidアプリのパターンの1つにApplicationクラスの参照ツリーの中にデータを持たせて、アプリの中からSingletonのように利用するパターンが有るように思う。しかし、Applicationクラスはプロセスに対して一意ではあるが、外部から起動なActivityやServiceの提供をしている場合などにアプリのプロセスが2つ以上になることはあるようだ。そうなると、アプリの中でSingletonだと思っていたデータは実はプロセスの中でのSingletonであるという点が問題になってくるケースがあるかもしれない。良い具体例は思いつかないけれど。

誰もが使うパターンだからと言って、そのまま心を無にして利用することの危険さを思い出した。

今一度自分の知識をおさらいして、間違えた理解がないのか、間違った考え方をしていないのかを確認する意味でもこの本は非常に有用だ。そして、それ以上に普段は意識することのないアプリよりも下のレイヤーに対する詳細な解説があるおかげで、やってはいけないパターンに思いを馳せたり、パフォーマンスを高める工夫を発見したり、バグが発生したときの効率の良い調査を実現できるだろう。

少なくとも、Androidアプリ開発を現役でバリバリ行う人には必読書であると感じている。