あらすじ
(概要)
Androidのインターナル解説書。
根底に流れるモバイルプラットフォームとしての哲学を丁寧に扱い,最新版(7,N/Nougat)までカバー。第2巻となる本書では,Androidの核心「Activity」と「Activityのライフサイクル」に焦点を定め,システムの心臓部を徹底解説。
無数のアプリがインテントなどの仕組みを通じて協調できる環境をシステムが総力を挙げて支援する。それは,モバイルOSのAndroidが選んだ道でした。
アプリのプロセスは,フォアグラウンドを退けば常にkillされ得る。必要とされた時に半自動的に再生成される。従来のアプリケーション開発とはまったく異なる画期的なメカニズムは,そのための切り札です。また,小さな画面のモバイルにおける画面遷移のデザインの複雑さや重要性はPCやWebよりも遥かに高い。この再生成と画面遷移という2つのモバイル特有の重要な問題を,統合してエレガントに解決しよう。
それが「Activity」です。
「Activityのライフサイクルを織り込んで,アプリの仕様,遷移のデザインを考えられるか」は,Android開発者としての最初の試金石です。システムの設計思想を踏まえて,きびきびと動けるアプリをつくりたい。そのような方々を強力にサポートする技術知識を集約してお届けします。
感情タグBEST3
Posted by ブクログ
Web+DB Press Plus
Androidを支える技術 II
真のマルチタスクに挑んだモバイルOSの心臓部
著:有野 和真
出版社:技術評論社
Android は、Javaと Linuxの世界であり、有限のメモリと電源を詰め込んだ組込み系のシステムと映りました
最終章から逆によむのがいいと、あまのじゃくの考えが浮かびました。
ブートローダから、カーネルのロード、これって昔のボードコンピュータ。
Activityは、スタックで管理していて、戻り値を保存している
メモリの関係で、Activityがいっぱいになったら、あるロジックで、Activityを自動的に消し込んでいって、
万が一、戻り値がのこっていて、Activityにもどろうとしていたら、Killされていたら、復元する
iphoneについては、Linux陣営がいろいろトライをしたが、結局 Android 以外はすべて絶命した
本書を読むにあたっては、オブジェクト指向の知識をあらかじめ用意しておかないと何が書いているかわからない。とくに、クラスとかインスタンスなどの用語を事前に仕入れておいたほうがいいと思います。
目次
本書について
第1章 AndroidとActivityの基礎知識
1.1 Activityが実現する世界
1.1.1 スマホにおける画面遷移の標準を提供
1.1.2 たくさんのアプリが共同でタスクをこなす
1.2 [入門]Activityプログラミング
1.2.1 まずはHelloActivityから
1.2.2 あるAというActivityからHelloActivityを起動してみる
1.2.3 テキストファイルを別のアプリで開いてみる
1.2.4 ギャラリーアプリなどで画像を選ぶ
1.2.5 Activityが再生成された時の対応
1.2.6 Activityのライフサイクルとは何か?
1.3 Activityはどう実現されているのか?
1.3.1 アプリのインストールとActivityの情報の管理
1.3.2 メモリ不足時のプロセスkill
1.3.3 Activityのスタック管理とライフサイクル
1.3.4 アプリのプロセスの生成とアプリから見たライフサイクル
1.3.5 システムの始まり ……[第6章]ブートローダーとinit
1.4 [速習]本書で登場するAndroidの構成要素のうち、本書の主役ではない部分
1.4.1 LooperとUIスレッド
1.4.2 HandlerとhandleMessage()
1.4.3 Binderとシステムサービス
1.5 Activityの仕組みを支えるデーモンとシステムサービス達
1.5.1 init.rcファイルの今と昔 ……mount_all
1.5.2 serviceセクション
1.5.3 本書で登場する、initから起動されるサービスとデーモン達
1.6 まとめ
第2章 [詳説]アプリのインストールとその情報
2.1 Google Playの衝撃 ……ユーザーも! 開発者も! 世界がつながるマーケット
2.1.1 Google Playを実現するために必要な2つの前提
2.1.2 かつての携帯電話のOSには、プロセスがなかった
2.1.3 アプリの権限を制限する仕組み
2.1.4 Androidは、Linuxのセキュリティ機構を応用したセキュリティモデル
2.2 アプリのインストール
2.2.1 アプリのインストールの概要
2.2.2 uidの割り振り
2.3 installdによるdataディレクトリの作成
2.3.1 dataディレクトリ
2.3.2 installdプロセスの起動
2.3.3 installdの権限
2.3.4 dataディレクトリの作成と権限設定
2.3.5 dataディレクトリに置かれるファイル達
2.3.6 dexoptコマンドによるバイトコードのインストール時処理
2.4 packages.xmlによるアプリの管理
2.4.1 packages.xmlの役割
2.4.2 実際のpackages.xmlの中身
2.4.3 起動時のpackages.xml読み込み
2.4.4 packages.xmlの権限と重要性
2.5 インテントとインテントの解決
2.5.1 インテントを送る側
2.5.2 インテントを受け取る側
2.5.3 インテントの解決
2.6 まとめ
第3章 カーネル側から見たメモリ不足
3.1 [基礎知識]メモリ不足時のカーネル側の振る舞い
3.1.1 メモリ不足時のカーネル側の振る舞い、全体像
3.1.2 Linuxカーネルのメモリ回収とoom_score_adj
3.1.3 lmkdデーモンとスコア更新
3.1.4 lowmemorykillerドライバ
3.2 Linuxカーネルのメモリ回収
3.2.1 Linuxのページフレーム回収の難しさ
3.2.2 Linuxのページフレーム回収の概要
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のスワップ事情
3.3.2 Low Memory Killerの基礎知識
3.3.3 lowmemorykillerモジュールとshrinker
3.3.4 lmkdデーモンとoom_score_adj更新
3.4 まとめ
第4章 [徹底攻略Ⅰ]スタックから見た!Activityのライフサイクル
4.1 ActivityStackとタスク ……遷移をデザインする技術
4.1.1 なぜActivityをスタック構造で管理するのか?
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を用いた
4.1.10 タスクとActivityStackについての考え方
4.2 アプリ側から見たメモリ不足
4.2.1 Androidにおける重要なプロセス
4.2.2 ActivityStackとoom_score_adj
4.3 Activityの生成 ……ActivityRecordとBundle
4.3.1 ActivityStackとActivityRecord
4.3.2 Bundleはどこにあるのか?
4.3.3 Bundleはどのくらいkillされないか?
4.3.4 ActivityRecordからのActivity生成
4.4 Activityのライフサイクル
4.4.1 Activityのライフサイクル概要
4.4.2 Activityのライフサイクルで実現したいこと
4.4.3 Activityのライフサイクル❶ ……ActivityStackの視点から
4.4.4 ActivityRecordの一時的な実体としてのActivity
4.4.5 Activityのライフサイクル❷ ……Activityインスタンスの視点から
4.4.6 Activityのライフサイクル❸ ……ActivityManagerServiceの視点から
4.4.7 [再考]Activityのライフサイクル ……Androidらしいアプリの姿
4.5 まとめ
第5章 [徹底攻略Ⅱ]アプリのプロセスから見る! Activityの生成と再生成
5.1 [基礎知識]アプリ側プロセスのActivity
5.1.1 プロセスの生成からアプリのプロセスになるまで
5.1.2 アプリのプロセスが、Activityを生成するまで
5.2 バイトコードを実行するプロセスとその始まり
5.2.1 app_processとそのmain()関数
5.2.2 ZygoteInitのmain()メソッドの3つの処理
5.2.3 preload()メソッドでロードされるクラス達
5.2.4 runSelectLoop()メソッド処理概要
5.2.5 ZygoteのforkAndSpecialize()とProcess.start()メソッド
5.2.6 startSystemServer()メソッドとSystemServerプロセス
5.3 ActivityThreadとは何か?
5.3.1 ActivityThreadの3つの重要なメソッド
5.3.2 ActivityThreadの役割
5.4 ActivityThreadの構成要素とmain()メソッド
5.4.1 ActivityThreadのmain()メソッド
5.4.2 ActivityThreadの2つの内部クラス
5.5 attach()メソッドとApplication Contextの誕生
5.5.1 attach()メソッドで行われること
5.5.2 handleBindApplication()でのApplication ContextとApplicationインスタンスの作成
5.5.3 attach()メソッドの呼び出しスタック
5.6 ActivityThreadのhandleMessage()
5.6.1 handleMessage()周辺の構造
5.6.2 ActivityとContextの誕生
5.6.3 Hのメッセージ概観
5.7 アプリの開始を見直す
5.7.1 本節で見ていくstartActivity()の呼び出しコード例
5.7.2 最初はインテントの解決
5.7.3 プロセスの開始と初期化
5.7.4 oom_score_adjによるプロセスのkill
5.7.5 「アプリの開始」解説の結びに
5.8 まとめ
第6章 Androidの始まり
6.1 ブートローダーとその周辺
6.1.1 電源を入れてからinitを起動するまでの概要
6.1.2 Android端末のパーティション
6.1.3 ブートイメージとリカバリーイメージ
6.2 Androidのブートローダー
6.2.1 LKブートローダーとは何か?
6.2.2 通常のブートローダーの処理
6.2.3 fastboot概要
6.2.4 ブートローダーの話、終わりに
6.3 initプロセスとその始まり
6.3.1 initプロセスとその処理概要
6.3.2 initプロセスの始まり
6.3.3 initのmain()関数後半
6.3.4 initのシグナル処理
6.4 プロパティ
6.4.1 プロパティの具体例
6.4.2 特殊なプロパティ
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 アクションとトリガー
6.5.4 さまざまなトリガー
6.5.5 serviceによるサービス定義
6.6 まとめ
A.1 ActivityのonSaveInstanceState()デフォルト実装
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()を眺める
おまけ
おわりに
索引
Posted by ブクログ
Android端末の内部でOSがどのような処理を行っているのかしっかりと理解してアプリ開発に役立てたい人におすすめ。筆者はガラケー時代から携帯端末のOS開発に携わった技術者とのことで、ITRON, SymbianなどのOSの話からWindows Mobileへの期待感、iPhone登場時のショックとその後のAndroidの成長などについて、本文とは別枠で書かれたコラムがとても面白かった。
Posted by ブクログ
職場の大先輩におすすめされ、しかも貸してもらえた。
ActivityというAndroidのアプリケーション構成要素を軸に、スマホというモバイル家電でいかにマルチタスクシステムを矛盾なく構築したか、が書かれている。
書店でAndroidコーナーに行くとアプリケーション開発手法ばかりが取り上げられている中で、純粋にAndroid内部について書かれた(しかも日本人原著の!)貴重な本。
Androidアプリ開発経験と、Linuxの知識がある人をメインの想定読者としているが、読み進める上で最低限必要なことはちゃんと説明してくれている。
コラムでは、著者がずっと関わってきた携帯ソフト開発業界の歴史などが書かれていて、それもそれだけで本にできるんじゃないかというぐらい面白い。
- メモリ不足対策
- スマホでは、ユーザがプロセスを明示的に終了することを期待できない上に、フラッシュストレージのデバイス特性により、スワップ領域を用意することもできないため、メモリが不足する状態が普通に発生する。
- そのため、メモリが不足したとき、Androidシステム上優先度の低いプロセスを自動で終了させる仕組みが必要となる。(例えば、裏に回ってしばらく使われていないActivityなど)
- Androidでは自動で終了させる仕組みは二段構えとなっており、少しメモリが不足してきたタイミングでAndroid独自ドライバによって行われるものと、かなりメモリが不足してきたタイミングでLinuxの提供するOOM killerによって行われるものとがある。
- どちらもoom_scoreに準じてどのプロセスを終了するかが選択される。
- lmkd : oom_scoreを調整するデーモンプロセス
- lowmemorykillerドライバ:linux kernelの提供するshrink_slab()を契機に、oom_scoreに準じてActivityを終了させる、Linux Kernel module。
- Activityの管理
- SystemServerプロセスのActivityManagerServiceクラスがActivityStackを管理する。
- 状態の変化に応じて、Activityにメッセージを送ったり、終了している場合はプロセスの再生成を行う。
- ActivityStackはActivityの再現に必要なすべての情報をもつActivityRecordを管理している。
- Activityの起動
- ZygoteサービスにActivityの起動依頼をしたら、zygoteサービスがforkし、setuidしたりlisten用のsocketを準備してから、指定したクラスのmainメソッドを呼び出す。
- 工夫
- 例外でスタックを巻き戻してから呼び出すことで、スタックを節約している(p.166)
- Java Runtimeを使うプロセスは(SystemServiceも)、app_processからforkすることで、実メモリを共有し、節約している
Posted by ブクログ
Android アプリは、開発チームのリーダーとして関わったり、 Tangoデバイス で Google Tango の実力の評価用のアプリを作った(ほぼ NDK で C++)くらいなので Activity や Intent について自分でがっつりと向き合ったことがなかったのでせいぜい画面の制御単位でしょ、くらいにしか認識してなかったのですが、こういう裏側の仕組みが 適切な粒度で説明されていると その思想がわかって良かったです。
想定読者にも書いてあるけど、まったくの初心者には厳しい本ながら、なんらかの核になる背景がある人だったらいい感じに読み進められると思います。(そして「物足りない」と思う部分はバックボーン知識によって変わってきそう)
作者の 「ここは端折る」「ここは詳述する」というメリハリの感覚が 良い加減でした。