WEB+DB PRESS plusシリーズAndroidを支える技術〈Ⅱ〉
──真のマルチタスクに挑んだモバイルOSの心臓部

書籍の概要

この本の概要

Androidのインターナル解説書。
根底に流れるモバイルプラットフォームとしての哲学を丁寧に扱い,最新版(7,N/Nougat)までカバー。

第2巻となる本書では,Androidの核心「Activity」と「Activityのライフサイクル」に焦点を定め,システムの心臓部を徹底解説。

無数のアプリがインテントなどの仕組みを通じて協調できる環境をシステムが総力を挙げて支援する。
それは,モバイルOSのAndroidが選んだ道でした。

アプリのプロセスは,フォアグラウンドを退けば常にkillされ得る。
必要とされた時に半自動的に再生成される。
従来のアプリケーション開発とはまったく異なる画期的なメカニズムは,そのための切り札です。

また,小さな画面のモバイルにおける画面遷移のデザインの複雑さや重要性はPCやWebよりも遥かに高い。

この再生成と画面遷移という2つのモバイル特有の重要な問題を,統合してエレガントに解決しよう。
それが「Activity」です。

「Activityのライフサイクルを織り込んで,アプリの仕様,遷移のデザインを考えられるか」は,Android開発者としての最初の試金石です。

システムの設計思想を踏まえて,きびきびと動けるアプリをつくりたい。
そのような方々を強力にサポートする技術知識を集約してお届けします。

こんな方におすすめ

  • Androidらしいアプリについて知りたい方
  • Androidできびきび動く,ツーランク上のアプリ開発に挑戦したい方
  • モバイルにおける画面遷移の複雑さと重要性を理解して,モバイルアプリ開発に活かしたい方
  • モバイルプラットフォームの今を本格的に知りたい方
  • Androidのソースコードを読むことになった方
  • Androidをテクニカルな観点で押さえたいとお考えのマネージャの方

本書に関するお知らせ

本書に関連する記事を公開しております。

この書籍に関連する記事があります!

スマホの今と近い未来について考える―スマホとPCとの違いを中心に
2016年のスマホ(Smartphone)の出荷台数は,世界で14億7,000台を超えています。

目次

本書について

第1章 AndroidとActivityの基礎知識 ──最重要は「Activity」

1.1 Activityが実現する世界 ……モバイルプラットフォームAndroidが選んだ道

  • 1.1.1 スマホにおける画面遷移の標準を提供
  • 1.1.2 たくさんのアプリが共同でタスクをこなす
    • 半手動のスワップアウトのような機構
    • アプリ間の連携の基盤
  • Column スマホがPCと違うのはどこだろうか? ……スマホの今と近い未来について

1.2 [入門]Activityプログラミング ……Activityの連携,インテント,Activityの再生成

  • 1.2.1 まずはHelloActivityから
  • 1.2.2 あるAというActivityからHelloActivityを起動してみる ……明示的インテント
  • 1.2.3 テキストファイルを別のアプリで開いてみる ……ACTION_VIEWインテント
  • 1.2.4 ギャラリーアプリなどで画像を選ぶ ……ACTION_PICKインテントとonActivityResult()
    • Toastで選択した画像のUriを表示する
  • 1.2.5 Activityが再生成された時の対応 ……onSaveInstanceState()とonRestoreInstanceState()
  • 1.2.6 Activityのライフサイクルとは何か?

1.3 Activityはどう実現されているのか? ……本書全体の見取り図

  • 1.3.1 アプリのインストールとActivityの情報の管理 ……[第2章]PackageManagerServiceとinstalld
  • 1.3.2 メモリ不足時のプロセスkill ……[第3章]lowmemorykillerとlmkd
  • 1.3.3 Activityのスタック管理とライフサイクル ……[第4章]ActivityManagerService
  • 1.3.4 アプリのプロセスの生成とアプリから見たライフサイクル ……[第5章]ZygoteとActivityThread
  • 1.3.5 システムの始まり ……[第6章]ブートローダーとinit
  • Column fork()システムコールとプロセスの生成

1.4 [速習]本書で登場するAndroidの構成要素のうち,本書の主役ではない部分 ……UIスレッド/Looper,Handler,Binder,システムサービス

  • 1.4.1 LooperとUIスレッド
    • Looperの2つの重要なstaticメソッド ……prepareMainLooper()とloop()メソッド
  • Column TLS
  • 1.4.2 HandlerとhandleMessage()
    • sendMessage()とhandleMessage()によるメッセージ処理
    • Handlerはnewしたスレッドが重要
    • Handlerの関連ドキュメント
  • 1.4.3 Binderとシステムサービス
    • システムサービスとSystemServer
  • Column UIスレッド以外でのLooperとHandlerの使用

1.5 Activityの仕組みを支えるデーモンとシステムサービス達 ……起点はinit.rcファイル

  • 1.5.1 init.rcファイルの今と昔 ……mount_all
  • 1.5.2 serviceセクション
  • Column Androidの「サービス」 ……4つの「サービス」
  • 1.5.3 本書で登場する,initから起動されるサービスとデーモン達
    • Zygoteサービス
    • installdサービス
    • lmkdサービス

1.6 まとめ

  • Column ITRONなどのリアルタイムOS ……モバイルプラットフォームの覇権争い❶[iPhone以前]
  • 第2章 [詳説]アプリのインストールとその情報 ──PackageManagerServiceとpackages.xml

2.1 Google Playの衝撃 ……ユーザーも! 開発者も! 世界がつながるマーケット

  • Column スマホ以前のアプリ事情
  • 2.1.1 Google Playを実現するために必要な2つの前提
  • 2.1.2 かつての携帯電話のOSには,プロセスがなかった
  • 2.1.3 アプリの権限を制限する仕組み
  • 2.1.4 Androidは,Linuxのセキュリティ機構を応用したセキュリティモデル
  • Column LinuxのユーザーとAndroidのユーザー
  • Column SELinuxとAndroid

2.2 アプリのインストール ……アプリをユーザーに見立てuidを割り振る

  • 2.2.1 アプリのインストールの概要
  • 2.2.2 uidの割り振り
  • Column gidとsharedUserId

2.3 installdによるdataディレクトリの作成 ……各アプリ専用のディレクトリを作るための特権

  • 2.3.1 dataディレクトリ
  • Column サーバーソケットのlisten()とaccept()によるコネクションの生成
  • 2.3.2 installdプロセスの起動
  • 2.3.3 installdの権限
  • Column Linuxのケーパビリティ
  • 2.3.4 dataディレクトリの作成と権限設定
  • 2.3.5 dataディレクトリに置かれるファイル達 ……SQLiteやSharedPreferencesなど
  • 2.3.6 dexoptコマンドによるバイトコードのインストール時処理
  • Column いろいろな「ユーザーID」とsetuid()ファミリー

2.4 packages.xmlによるアプリの管理 ……アプリと,uid一覧&付加情報の関係を管理

  • 2.4.1 packages.xmlの役割 ……Android版の/etc/passwd
  • 2.4.2 実際のpackages.xmlの中身 ……package要素
  • Column package要素以外のpackages.xmlの要素
    • fatバイナリとNDK
  • 2.4.3 起動時のpackages.xml読み込み
  • 2.4.4 packages.xmlの権限と重要性

2.5 インテントとインテントの解決 ……ユーザーのために。Androidらしさの根幹にインテントあり

  • 2.5.1 インテントを送る側 ……インテントを使ったActivityの呼び出し
  • 2.5.2 インテントを受け取る側 ……AndroidManifest.xmlとintent-filter
  • Column 暗黙的インテントと明示的インテント
  • 2.5.3 インテントの解決 ……PackageManagerServiceのresolveIntent()とintent-filter
  • 2.5.4 intent-filterを持つその他の要素達
    • <service>要素とSDKのService
    • <receiver>要素とBroadCastReceiver

2.6 まとめ

  • Column Activity選択画面とqueryIntentActivities()
  • 第3章 カーネル側から見たメモリ不足 ──lmkdとLow Memory Killerという存在

3.1 [基礎知識]メモリ不足時のカーネル側の振る舞い ……プロセスをkillする方針と仕組みの違い

  • 3.1.1 メモリ不足時のカーネル側の振る舞い,全体像
  • 3.1.2 Linuxカーネルのメモリ回収とoom_score_adj
  • 3.1.3 lmkdデーモンとスコア更新
  • 3.1.4 lowmemorykillerドライバ
  • Column Symbian OS ……モバイルプラットフォームの覇権争い❷[iPhone以前]

3.2 Linuxカーネルのメモリ回収 ……わりと勝手な回収になる理由,豪傑のOOM Killer

  • 3.2.1 Linuxのページフレーム回収の難しさ
    • ゾーンアロケータとslabアロケータ
  • 3.2.2 Linuxのページフレーム回収の概要
    • slabアロケータ由来のメモリ解放とshrink_slab()呼び出し
  • 3.2.3 OOM Killerとoom_score
  • 3.2.4 oom_score_adjとOOM Killerの挙動のカスタマイズ

3.3 AndroidのLow Memory Killer ……段階的に振る舞いを変える,エレガントな機構

  • 3.3.1 フラッシュメモリの仕組みとAndroidのスワップ事情
  • Column Androidでスワップが行われるのは,どのような時?
  • 3.3.2 Low Memory Killerの基礎知識 ……限定した用途のシステムならではの対応策
  • 3.3.3 lowmemorykillerモジュールとshrinker
  • Column Low Memory Killerの変遷
    • Linuxカーネルのshrink_slab()によるキャッシュの解放
    • lowmemorykillerモジュールが提供するshrinkerの振る舞い
    • OOM Killerとshrink_slab()の比較
    • lowmemorykillerモジュールの段階的なプロセスkill ……minfreeとadjパラメータ
  • Column oom_score_adjとoom_adj
  • 3.3.4 lmkdデーモンとoom_score_adj更新

3.4 まとめ

    第4章 [徹底攻略Ⅰ]スタックから見た!Activityのライフサイクル ──ActivityStackとActivityManagerServiceが形づくるAndroidらしさ

4.1 ActivityStackとタスク ……遷移をデザインする技術

  • 4.1.1 なぜActivityをスタック構造で管理するのか?
  • Column より大きな画面への挑戦
  • 4.1.2 タスク
  • 4.1.3 タスク作成を意識する難しさ
  • 4.1.4 Activityを管理するスタック ……ActivityStack概要
  • 4.1.5 ActivityStackとタスクの戻り先フラグ
  • 4.1.6 launchModeとインテントフラグ
  • 4.1.7 タスクとActivityStackの具体例❶ ……通常のActivity起動のケース
  • 4.1.8 タスクとActivityStackの具体例❷ ……launchModeがsingleTaskのケース
  • 4.1.9 タスクとActivityStackの具体例❸ ……インテントフラグのFLAG_ACTIVITY_CLEAR_TOPを用いたActivityStackの操作
  • Column ホーム画面からのアプリの起動の不思議
  • 4.1.10 タスクとActivityStackについての考え方

4.2 アプリ側から見たメモリ不足 ……重要度の低いActivityを積極的にkillしていく

  • 4.2.1 Androidにおける重要なプロセス
  • 4.2.2 ActivityStackとoom_score_adj ……ActivityManagerServiceの役割

4.3 Activityの生成 ……ActivityRecordとBundle

  • 4.3.1 ActivityStackとActivityRecord
  • 4.3.2 Bundleはどこにあるのか? ……ActivityRecordとBundle
  • 4.3.3 Bundleはどのくらいkillされないか? ……oom_score_adjに見る,SystemServerプロセスとActivityのプロセスのkillされにくさ
  • 4.3.4 ActivityRecordからのActivity生成 ……ActivityManagerService側の処理
    • プロセスが存在している場合 ……scheduleLaunchActivity()呼び出し
    • プロセスが存在しない場合 ……Process.start()呼び出し
  • Column Bundleはファイルに書き出されないのか?
  • Column 組み込みLinux勢[1] ……モバイルプラットフォームの覇権争い❸[iPhone以前]

4.4 Activityのライフサイクル ……Androidの「コア」に迫る

  • 4.4.1 Activityのライフサイクル概要
  • 4.4.2 Activityのライフサイクルで実現したいこと ……まずはユーザーの視点から
    • Activityのライフサイクルで実現したいこと ……アプリ開発者の視点から
  • 4.4.3 Activityのライフサイクル❶ ……ActivityStackの視点から
  • 4.4.4 ActivityRecordの一時的な実体としてのActivity
  • 4.4.5 Activityのライフサイクル❷ ……Activityインスタンスの視点から
  • Column Windows CEとWindows Mobile ……モバイルプラットフォームの覇権争い❹[iPhone以前]
  • 4.4.6 Activityのライフサイクル❸ ……ActivityManagerServiceの視点から
  • Column 裏のActivityで計算を進める難しさ
  • 4.4.7 [再考]Activityのライフサイクル ……Androidらしいアプリの姿
  • Column プールとキャッシュとActivity

4.5 まとめ

  • Column pauseだけど見える状態 ……半透明とマルチウィンドウ
  • Column そして,iPhoneがやってきた ……モバイルプラットフォームの覇権争い❺[iPhone登場]
  • 第5章 [徹底攻略Ⅱ]アプリのプロセスから見る! Activityの生成と再生成 ──ZygoteとActivityThread

5.1 [基礎知識]アプリ側プロセスのActivity ……ActivityのライフサイクルでZygoteとActivityThreadが果たす役割

  • 5.1.1 プロセスの生成からアプリのプロセスになるまで ……ZygoteのforkからActivityThreadのattach()まで
  • 5.1.2 アプリのプロセスが,Activityを生成するまで
  • Column Windows Mobile ……モバイルプラットフォームの覇権争い❻[iPhone以後]

5.2 バイトコードを実行するプロセスとその始まり ……app_processとZygote

  • 5.2.1 app_processとそのmain()関数
    • クラスを直接実行する例 ……pmコマンドを例に
    • Zygoteモードでの起動
    • Zygoteモード時のapp_process ……main()関数の概要
  • 5.2.2 ZygoteInitのmain()メソッドの3つの処理
  • 5.2.3 preload()メソッドでロードされるクラス達
  • 5.2.4 runSelectLoop()メソッド処理概要
    • まず,ソケットを配列に入れてselectReadable()を呼ぶ
    • selectReadable()で"zygote"ソケットのインデックスが返ってきた時の処理 ……ZygoteConnectionの追加
    • selectReadable()でZygoteConnetionのソケットのインデックスが返ってきた時の処理 ……実際のfork処理
  • 5.2.5 ZygoteのforkAndSpecialize()とProcess.start()メソッド
    • ZygoteConnectionのhandleChildProc()メソッドによる子プロセスの開始
  • 5.2.6 startSystemServer()メソッドとSystemServerプロセス
    • SystemServerのrun()メソッド ……システムサービス群の起動
    • システムサービス群の起動
  • Column 組み込みLinux勢[2] ……モバイルプラットフォームの覇権争い❼[iPhone以後]

5.3 ActivityThreadとは何か? ……ActivityThreadの,3つの重要メソッドと5つの役割

  • 5.3.1 ActivityThreadの3つの重要なメソッド
  • 5.3.2 ActivityThreadの役割

5.4 ActivityThreadの構成要素とmain()メソッド ……UIスレッドの起点,ActivityThreadのインスタンス作成

  • Column ActivityThreadとApplicationクラス
  • 5.4.1 ActivityThreadのmain()メソッド ……アプリの全人生を司る
    • Looper周辺の処理 ……UIスレッドの正体
    • ActivityThreadのインスタンス生成
  • 5.4.2 ActivityThreadの2つの内部クラス ……HとApplicationThread
    • クラスH ……Handlerのサブクラス
    • ApplicationThread ……Binder越しに呼び出しを受け取るクラス

5.5 attach()メソッドとApplication Contextの誕生 ……アプリの起動処理の根幹

  • 5.5.1 attach()メソッドで行われること
  • 5.5.2 handleBindApplication()でのApplication ContextとApplicationインスタンスの作成
  • 5.5.3 attach()メソッドの呼び出しスタック

5.6 ActivityThreadのhandleMessage() ……クラスHとライフサイクル関連処理

  • 5.6.1 handleMessage()周辺の構造 ……scheduleXX()とhandleXX()
  • 5.6.2 ActivityとContextの誕生 ……handleLaunchActivity()の処理
  • 5.6.3 Hのメッセージ概観

5.7 アプリの開始を見直す ……第2章から第5章までの知識を総動員

  • 5.7.1 本節で見ていくstartActivity()の呼び出しコード例
  • 5.7.2 最初はインテントの解決 ……[第2章]PackageManagerService
  • 5.7.3 プロセスの開始と初期化 ……[第4章]ActivityStack,[第5章]ActivityThread
  • 5.7.4 oom_score_adjによるプロセスのkill ……[第3章]Low Memory Killer
  • 5.7.5 「アプリの開始」解説の結びに

5.8 まとめ

  • Column Android ……モバイルプラットフォームの覇権争い❽[iPhone以後]
  • 第6章 Androidの始まり ──ブートローダーとinitプロセス

6.1 ブートローダーとその周辺 ……電源ONからカーネルに実行を移すまで

  • 6.1.1 電源を入れてからinitを起動するまでの概要
  • 6.1.2 Android端末のパーティション
    • abootパーティション ……ブートローダーが保存されているパーティション
    • bootパーティション ……boot.imgが保存されているパーティション
    • cacheパーティション
    • recoveryパーティション
    • systemパーティション
    • userdataパーティション
  • 6.1.3 ブートイメージとリカバリーイメージ

6.2 Androidのブートローダー ……LKブートローダーを例に

  • 6.2.1 LKブートローダーとは何か?
  • 6.2.2 通常のブートローダーの処理
  • Column ブートローダーの今と昔
    • Device Tree
  • 6.2.3 fastboot概要
    • fastbootモードでの起動方法
  • Column rootを取得する? ……何をしているのか?
    • fastbootコマンド一覧
  • Column fastbootいろいろ
  • 6.2.4 ブートローダーの話,終わりに

6.3 initプロセスとその始まり ……initのmain()関数から見えてくる役割

  • 6.3.1 initプロセスとその処理概要
  • 6.3.2 initプロセスの始まり ……main()関数前半の,初期化の部分
  • Column epoll()による複数のファイルディスクリプタ待ち
  • 6.3.3 initのmain()関数後半 ……無限ループの部分
  • 6.3.4 initのシグナル処理 ……signal_handler
    • SIGCHLD_handler()シグナルハンドラ
    • handle_signal()コールバックとServiceのReap()処理
    • ServiceのReap()メソッドによるプロセスの終了と再起動処理
  • Column シグナルとwaitpid()による子プロセスの終了 ……zombieプロセスとその終了

6.4 プロパティ ……システム設定を保持する小さなストレージ

  • 6.4.1 プロパティの具体例 ……setpropとgetpropを中心に
    • USBケーブルを使わずにtcpipでadb connectする
  • 6.4.2 特殊なプロパティ ……ro.とctl.で始まるプロパティ
    • ctl.stopによるstopコマンドの実装
  • 6.4.3 プロパティのlistener
  • 6.4.4 プロパティの実装

6.5 init.rcとその内容 ……依存関係,異常終了や再起動を引き受ける基盤

  • 6.5.1 PCのrcスクリプトとの比較
  • 6.5.2 Android Init Language概要
  • 6.5.3 アクションとトリガー
  • Column Upstartとsystemd
  • 6.5.4 さまざまなトリガー
    • ラベルのトリガー
    • プロパティの値に応じたトリガー
  • 6.5.5 serviceによるサービス定義
    • socketとonrestart

6.6 まとめ

    Appendix ActivityとViewツリーの狭間で ──第Ⅱ巻と第Ⅰ巻の関係が見えるViewツリーの状態の保存

A.1 ActivityのonSaveInstanceState()デフォルト実装 ……superは何を行っている?

  • A.1.1 基本事項のおさらい
  • A.1.2 実際のActivityのonSaveInstanceState()のコード
  • A.1.3 PhoneWindowのsaveHierarchyState()
  • A.1.4 ParcelとParcelable
  • A.1.5 ViewのsaveHierarchyState()より先の処理
  • A.1.6 dispatchSaveInstanceState()を眺める
  • Column WebOS ……モバイルプラットフォームの覇権争い❾[iPhone以後]

おまけ

おわりに

索引

著者プロフィール

有野和真(ありのかずま)

新卒でガラケー向けのブラウザ会社に入り組み込み業界で働いた後,2005年にマイクロソフトディベロップメントに移り.NETのサーバーサイド分野であるSharePointの開発に従事。2009年からフリーランスになり,機械学習関連のプロジェクトやスパコンの独自GPGPU開発に携わる傍ら,Androidのお絵描きアプリ「LayerPaint」を共同開発。