Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
#DroidKaigi #room2
/66
シームレスに遷移可能な画面を
他のアプリに提供する方法
2019/2/7 DroidKaigi 2019
エムスリー株式会社 星川 貴樹
1
#DroidKaigi #room2
/66
プロフィール
- 星川貴樹 (@oboenikui)
- エムスリー株式会社所属 (2017〜)
- Android & セキュリティエンジニア
- 初めてのAndroidはIS01
2
#DroidKaigi #room2
/66
エムスリー株式会社
- 医師向けプラットフォームサービスなど医療系Webサービスの会社
- ブースも出しているので遊びに来てね!
- We Are Hiring!!
3
#DroidKaigi #room2
/66
本セッションについて
ゴール
- Chrome Custom Tabsや
Google Now Launcherをヒン
トに、シームレスな遷移の実装
を理解する
- 関連技術としてプロセス間通信
(...
#DroidKaigi #room2
/66
注意事項
- 実用的な話よりニッチな話多めです
- 本セッションで紹介された内容をプロダクトに活かす場合、危険性を
含めて十分議論の上ご活用ください
5
#DroidKaigi #room2
/66
本当に実用的な話だけを聞きたい方へ
6
#DroidKaigi #room2
/66
アプリを跨いだ
Activity遷移でも
Shared Elementが使えます
https://developer.android.com/training/transitions/start-a...
#DroidKaigi #room2
/66
ご清聴ありがとうございました
8
#DroidKaigi #room2
/66
ここから先はニッチな話です
9
#DroidKaigi #room2
/66
本セッションのきっかけ
数年前、自分には動作原理がよくわからない
Androidアプリが3つあった
10
#DroidKaigi #room2
/66
1つめ:マルチアカウントアプリ
- 他のapkをアプリ内で起動するアプリ
- リフレクションでシステムのapkロードの仕組
みを使う
- 自分のActivityThreadを他のものであるか
のよう...
#DroidKaigi #room2
/66
2つめ:Chrome Custom Tabs
- アプリが提供するWebViewのようにChromeを
開く機能
- Chromeで開いたり、WebViewを使うより高速
に切り替わる
- Cust...
#DroidKaigi #room2
/66
3つめ:Google Now Launcher
- 2013年のNexus 5向けランチャーが初出
- ランチャーの左からGoogle Nowが出てくる
- ランチャーアプリ内にはGoogle No...
#DroidKaigi #room2
/66
Agenda
- アプリ間の遷移をスムーズにする技術
- Chrome Custom Tabsで使われているプロセス間通信の仕組みを知る
- (Custom Tabから通常のChromeへの遷移の仕...
#DroidKaigi #room2
/66
アプリ間の遷移をスムーズにする技術
15
#DroidKaigi #room2
/66
Chrome Custom Tabs
- Chrome Custom Tabsは、Chromeのタブをア
プリのWebViewのように表示する機能
- アプリ内WebViewやIntentによるブラ...
#DroidKaigi #room2
/66
参考リポジトリの話
- Google Chromeはオープンソースではないので、代わりに
Chromiumのソースを参考に話をします
https://github.com/chromium/chro...
#DroidKaigi #room2
/66
Chrome Custom Tabsの動作を知る
CustomTabActivity ChromeTabbedActivity任意のアプリ
アプリ間の遷移をスムーズにする技術
18
#DroidKaigi #room2
/66
Chrome Custom Tabsの動作を知る
CustomTabActivity ChromeTabbedActivity任意のアプリ
遷移前に事前処理を行う
アプリ間の遷移をスムーズにする技術...
#DroidKaigi #room2
/66
遷移前後の処理
任意のアプリ
アプリ間の遷移をスムーズにする技術
20
#DroidKaigi #room2
/66
遷移前後の処理
任意のアプリ
CustomTabsService
IPCで開くURLを事前に通知
アプリ間の遷移をスムーズにする技術
21
#DroidKaigi #room2
/66
遷移前後の処理
任意のアプリ
渡されたURLを基にコネクショ
ンを張るなど事前処理を行う
アプリ間の遷移をスムーズにする技術
CustomTabsService
22
#DroidKaigi #room2
/66
遷移前後の処理
CustomTabActivity任意のアプリ
ユーザーアクションにより
Custom Tabを起動
アプリ間の遷移をスムーズにする技術
CustomTabsService
23
#DroidKaigi #room2
/66
遷移前後の処理
CustomTabActivity任意のアプリ
CustomTabsService
事前に張ったコネクションを
利用して高速にページを表示
アプリ間の遷移をスムーズにする技術
24
#DroidKaigi #room2
/66
ポイント
- サードパーティアプリからChromeのServiceにバインドする
- プロセス間通信 (IPC) を行う必要がある
- 実装はAIDLを用いている
アプリ間の遷移をスムーズにする技術...
#DroidKaigi #room2
/66
AndroidのIPC
- Binderと呼ばれる仕組みでデータのやりとりを行う
- Parcelという仕組みでデータの読み書きを行う
- Parcelに読み書きできるのはプリミティブ型、Parce...
#DroidKaigi #room2
/66
Serviceにバインドする
- ActivityとServiceがやりとりするにはバインドする必要がある
- バインドする方法は以下の3通り
バインド方法 プロセスの制約 スレッドの制約
Bind...
#DroidKaigi #room2
/66
AIDLの紹介
- Android インターフェース定義言語 (AIDL)
- 文法はJavaのinterfaceの記法に近い
- プロセス間通信 (IPC) を行うために用いる手法の1つ
- その...
#DroidKaigi #room2
/66
AIDLの仕組み
アプリ間の遷移をスムーズにする技術
.aidlファイル
Stubクラス
(abstract)
Proxyクラス interface
クライアント側用
リモート側用
クラス自動生成
...
#DroidKaigi #room2
/66
AIDLの仕組み
アプリ間の遷移をスムーズにする技術
.aidlファイル
Stubクラス
(abstract)
Proxyクラス interface
クライアント側用
リモート側用
クラス自動生成
...
#DroidKaigi #room2
/66
AIDLの仕組み
アプリ間の遷移をスムーズにする技術
.aidlファイル
Stubクラス
(abstract)
Proxyクラス interface
クライアント側用
リモート側用
クラス自動生成
...
#DroidKaigi #room2
/66
AIDLの仕組み
アプリ間の遷移をスムーズにする技術
.aidlファイル
Stubクラス
(abstract)
Proxyクラス interface
クライアント側用
リモート側用
クラス自動生成
...
#DroidKaigi #room2
/66
AIDLの仕組み
メソッド呼び出し
Parcelに
格納
クライアント側 (例:Activity) リモート側 (例:Service)
Proxyクラス
binder binder
Parcelから...
#DroidKaigi #room2
/66
AIDLの仕組み
メソッド呼び出し
Parcelに
格納
クライアント側 (例:Activity) リモート側 (例:Service)
Proxyクラス
binder binder
Parcelから...
#DroidKaigi #room2
/66
AIDLの仕組み
メソッド呼び出し
Parcelに
格納
クライアント側 (例:Activity) リモート側 (例:Service)
Proxyクラス
binder binder
Parcelから...
#DroidKaigi #room2
/66
AIDLの仕組み
メソッド呼び出し
Parcelに
格納
クライアント側 (例:Activity) リモート側 (例:Service)
Proxyクラス
binder binder
Parcelから...
#DroidKaigi #room2
/66
余談:シームレスなActivity間の遷移
CustomTabActivity ChromeTabbedActivity任意のアプリ
Activityが切り替わっているが
JavaScriptの状態...
#DroidKaigi #room2
/66
余談:シームレスなActivity間の遷移
- Custom Tabから通常のChromeの画面への遷移
があまりに自然すぎる
- SharedElementは単に新たなViewをアニメー
ションさ...
#DroidKaigi #room2
/66
状態が保存される遷移の実装
- Viewを含むWebページの状態を保持するオブジェクトをActivity間
で共有
- 生成時のContextは、Application Contextを
Conte...
#DroidKaigi #room2
/66
動的なコンポーネントを提供する技術
40
#DroidKaigi #room2
/66
使い道
- Google Nowのような汎用の情報画面を表示する
(端末メーカー向き)
- アプリAの一部機能をアプリBでも使いたいが、アプリB側には実装を
持たせたくない場合
動的なコンポーネント...
#DroidKaigi #room2
/66
Google Nowランチャーの動作を知る
- 右の動きは全てランチャーアプリ上での挙動
- 連携のためのコードを除き、ランチャー側に
Google Nowの実装は存在しない
- ランチャーのコンテ...
#DroidKaigi #room2
/66
Google Nowランチャーの動作を知る
- 動作原理さえ知っていればランチャーである必
要もない
- ただしGoogle Nowの場合、システムアプリで
しか利用できないように制限されている
動...
#DroidKaigi #room2
/66
参考リポジトリの話
- GoogleアプリはOSSではなく、規約上リバースエンジニアリングで
得た情報を発表するわけにはいかないので、同じ動きをするOSSを参
考に話します
https://gith...
#DroidKaigi #room2
/66
Google Nowランチャーの4つのポイント
1. ServiceによってWindowManager#addViewで追加されたViewである
2. 表示するActivityのWindowMana...
#DroidKaigi #room2
/66
WindowManagerについて
右:Facebook Messengerの例
- 一般アプリがWindowManagerを直接使う機会
は多くない
- 最も利用するケースは他のアプリの上に常に表...
#DroidKaigi #room2
/66
WindowManagerについて
- 一般アプリがWindowManagerを直接使う機会
は多くない
- 最も利用するケースは他のアプリの上に常に表
示するとき
- 実際にはActivityで表...
#DroidKaigi #room2
/66
WindowManagerについて
WindowManager
Service
- 一般アプリがWindowManagerを直接使う機会
は多くない
- 最も利用するケースは他のアプリの上に常に表
...
#DroidKaigi #room2
/6649
Androidの表示レイヤー
WALLPAPER
表示内容に合わせて現在33層
のレイヤーに分けられている
アプリケーションレイヤ
PHONE
SYSTEM_ALERT
バッテリー不足などの
シ...
#DroidKaigi #room2
/6650
オーバーレイコンテンツの場合
WALLPAPER
他の重要でないアラートなど
よりも上に表示される
Activityに紐付かない画面の
提供が可能なので、常に画面
上に表示しておくことが可能
ア...
#DroidKaigi #room2
/6651
Google Nowの場合
WALLPAPER
アプリケーションレイヤに表
示する
表示がActivityと紐づくた
め、他のアプリの上に表示さ
れることはない
PHONE
SYSTEM_ALE...
#DroidKaigi #room2
/66
アプリケーションレイヤの制限
- セキュリティ上、任意のServiceが勝手にアプリケーションレイヤ
にViewを追加できるべきではない
- 対策として、WindowManagerが各ウィンドウごと...
#DroidKaigi #room2
/66
画面の状態変更やボタン操作に対応する
Activityではレイアウトに係る処理をWindowクラスで行っているが、
ServiceにはWindowクラスを使う基本的な手段が存在しない
WindowM...
#DroidKaigi #room2
/66
System Process
Process BProcess A
Activity
画面の状態変更やボタン操作に対応する
またこれらはそれぞれ別プロセスで動くため、Windowインスタンスを
Se...
#DroidKaigi #room2
/66
ServiceでWindowクラスのインスタンス生成
- Windowはabstractクラスで、実装はPhoneWindowクラス
- PhoneWindowクラスはinternalクラスなので、...
#DroidKaigi #room2
/66
PhoneWindowのインスタンスを生成できる箇所
動的なコンポーネントを提供する技術
https://search.siprop.org/android-9.0.0_r1.0/search?q=...
#DroidKaigi #room2
/66
PhoneWindowのインスタンスを生成できる箇所
https://search.siprop.org/android-9.0.0_r1.0/search?q=%22new+PhoneWindow...
#DroidKaigi #room2
/66
ServiceでWindowクラスのインスタンス生成
- Windowはabstractクラスで、実装はPhoneWindowクラス
- PhoneWindowクラスはinternalクラスなので、...
#DroidKaigi #room2
/66
ここまでのポイント
1. ServiceによってWindowManager#addViewで追加されたViewである
2. 表示するActivityのレイアウトパラメータを使ってアプリケーションレイ...
#DroidKaigi #room2
/6660
ここまでのポイント
1. ServiceによってWindowManager#addViewで追加されたViewである
2. 表示するActivityのレイアウトパラメータを使ってアプリケーション...
#DroidKaigi #room2
/66
ここまでのポイント
1. ServiceによってWindowManager#addViewで追加されたViewである
2. 表示するActivityのレイアウトパラメータを使ってアプリケーションレイ...
#DroidKaigi #room2
/66
IPCでランチャーアプリと通信
動的なコンポーネントを提供する技術
ランチャーアプリ
移動すべき座標を通知
62
Google Nowの
サービス
#DroidKaigi #room2
/6663
IPCでランチャーアプリと通信
動的なコンポーネントを提供する技術
ランチャーアプリ
Google Nowの
サービス
移動することを通
知
#DroidKaigi #room2
/66
最終的な実装結果
動的なコンポーネントを提供する技術
簡易的にViewPagerのページめくりと同期させた場
合、右のようになる
(参考リポジトリの実行結果)
64
#DroidKaigi #room2
/66
まとめと考察
- Chrome Custom TabsではAIDLによるプロセス間通信を行う
- 同様にAIDLで定めたプロトコルをサードパーティに提供し、Activity
起動前の準備を行うことが...
#DroidKaigi #room2
/66
ご清聴ありがとうございました
66
Prochain SlideShare
Chargement dans…5
×

DroidKaigi 2019 シームレスに遷移可能な画面を他のアプリに提供する方法

2 111 vues

Publié le

アプリの画面のように起動し、ユーザーの選択でシームレスにChromeに移ることもできるChrome Custom Tabsや、ランチャーアプリから横スワイプするだけで表示されるGoogle Nowのように、UXを損なうことなくアプリ間を遷移するためには、場合によって通常のIntentによるActivityの遷移とは異なる方法を取る必要があります。
本セッションでは、上で挙げた2つのアプリを始めとした、シームレスな連携をしているアプリの実装がどのようになっているのかを紐解き、その上で他のアプリに画面を提供する方法について考察します。
https://droidkaigi.jp/2019/timetable/70954
アニメーション付きのスライドはこちらからご覧になれます。
https://docs.google.com/presentation/d/e/2PACX-1vShGVlmPnMc2k8pqpTn0rTQiUG8Tj2nAOCcXkQqnf04I7ybs-VnW9rDf4m5-b4XGXklo0mxKTibtyV7/pub?start=false&loop=false&delayms=3000

Publié dans : Ingénierie
  • Soyez le premier à commenter

DroidKaigi 2019 シームレスに遷移可能な画面を他のアプリに提供する方法

  1. 1. #DroidKaigi #room2 /66 シームレスに遷移可能な画面を 他のアプリに提供する方法 2019/2/7 DroidKaigi 2019 エムスリー株式会社 星川 貴樹 1
  2. 2. #DroidKaigi #room2 /66 プロフィール - 星川貴樹 (@oboenikui) - エムスリー株式会社所属 (2017〜) - Android & セキュリティエンジニア - 初めてのAndroidはIS01 2
  3. 3. #DroidKaigi #room2 /66 エムスリー株式会社 - 医師向けプラットフォームサービスなど医療系Webサービスの会社 - ブースも出しているので遊びに来てね! - We Are Hiring!! 3
  4. 4. #DroidKaigi #room2 /66 本セッションについて ゴール - Chrome Custom Tabsや Google Now Launcherをヒン トに、シームレスな遷移の実装 を理解する - 関連技術としてプロセス間通信 (IPC) の方法を理解する 話さないこと - Fragment間をスムーズに遷移 する方法など - アニメーションの付け方 - ConstraintLayout, MotionLayout ... 4
  5. 5. #DroidKaigi #room2 /66 注意事項 - 実用的な話よりニッチな話多めです - 本セッションで紹介された内容をプロダクトに活かす場合、危険性を 含めて十分議論の上ご活用ください 5
  6. 6. #DroidKaigi #room2 /66 本当に実用的な話だけを聞きたい方へ 6
  7. 7. #DroidKaigi #room2 /66 アプリを跨いだ Activity遷移でも Shared Elementが使えます https://developer.android.com/training/transitions/start-activity#start-with-element 7
  8. 8. #DroidKaigi #room2 /66 ご清聴ありがとうございました 8
  9. 9. #DroidKaigi #room2 /66 ここから先はニッチな話です 9
  10. 10. #DroidKaigi #room2 /66 本セッションのきっかけ 数年前、自分には動作原理がよくわからない Androidアプリが3つあった 10
  11. 11. #DroidKaigi #room2 /66 1つめ:マルチアカウントアプリ - 他のapkをアプリ内で起動するアプリ - リフレクションでシステムのapkロードの仕組 みを使う - 自分のActivityThreadを他のものであるか のように改竄して対象アプリを騙す ※ DroidKaigi 2018で発表済みなので詳しくはスライド参照 https://www.slideshare.net/TakakiHoshikawa/how-multiaccount-app-works 11
  12. 12. #DroidKaigi #room2 /66 2つめ:Chrome Custom Tabs - アプリが提供するWebViewのようにChromeを 開く機能 - Chromeで開いたり、WebViewを使うより高速 に切り替わる - Custom TabからChromeを開く際、Activity が切り替わっているのにウェブページの状態が 引き継がれている 12
  13. 13. #DroidKaigi #room2 /66 3つめ:Google Now Launcher - 2013年のNexus 5向けランチャーが初出 - ランチャーの左からGoogle Nowが出てくる - ランチャーアプリ内にはGoogle Nowのコード が入っていない! (Googleアプリの画面が表示されている) 13
  14. 14. #DroidKaigi #room2 /66 Agenda - アプリ間の遷移をスムーズにする技術 - Chrome Custom Tabsで使われているプロセス間通信の仕組みを知る - (Custom Tabから通常のChromeへの遷移の仕方を知る) - 動的なコンポーネントを提供する技術 - GoogleアプリはどのようにしてGoogle Nowを表示しているか 14
  15. 15. #DroidKaigi #room2 /66 アプリ間の遷移をスムーズにする技術 15
  16. 16. #DroidKaigi #room2 /66 Chrome Custom Tabs - Chrome Custom Tabsは、Chromeのタブをア プリのWebViewのように表示する機能 - アプリ内WebViewやIntentによるブラウザ起 動より高速 - Custom TabからChromeの画面にシームレスに 遷移する アプリ間の遷移をスムーズにする技術 16
  17. 17. #DroidKaigi #room2 /66 参考リポジトリの話 - Google Chromeはオープンソースではないので、代わりに Chromiumのソースを参考に話をします https://github.com/chromium/chromium https://github.com/kuoruan/Chromium-Android (NDKビルド済み) アプリ間の遷移をスムーズにする技術 17
  18. 18. #DroidKaigi #room2 /66 Chrome Custom Tabsの動作を知る CustomTabActivity ChromeTabbedActivity任意のアプリ アプリ間の遷移をスムーズにする技術 18
  19. 19. #DroidKaigi #room2 /66 Chrome Custom Tabsの動作を知る CustomTabActivity ChromeTabbedActivity任意のアプリ 遷移前に事前処理を行う アプリ間の遷移をスムーズにする技術 19
  20. 20. #DroidKaigi #room2 /66 遷移前後の処理 任意のアプリ アプリ間の遷移をスムーズにする技術 20
  21. 21. #DroidKaigi #room2 /66 遷移前後の処理 任意のアプリ CustomTabsService IPCで開くURLを事前に通知 アプリ間の遷移をスムーズにする技術 21
  22. 22. #DroidKaigi #room2 /66 遷移前後の処理 任意のアプリ 渡されたURLを基にコネクショ ンを張るなど事前処理を行う アプリ間の遷移をスムーズにする技術 CustomTabsService 22
  23. 23. #DroidKaigi #room2 /66 遷移前後の処理 CustomTabActivity任意のアプリ ユーザーアクションにより Custom Tabを起動 アプリ間の遷移をスムーズにする技術 CustomTabsService 23
  24. 24. #DroidKaigi #room2 /66 遷移前後の処理 CustomTabActivity任意のアプリ CustomTabsService 事前に張ったコネクションを 利用して高速にページを表示 アプリ間の遷移をスムーズにする技術 24
  25. 25. #DroidKaigi #room2 /66 ポイント - サードパーティアプリからChromeのServiceにバインドする - プロセス間通信 (IPC) を行う必要がある - 実装はAIDLを用いている アプリ間の遷移をスムーズにする技術 25
  26. 26. #DroidKaigi #room2 /66 AndroidのIPC - Binderと呼ばれる仕組みでデータのやりとりを行う - Parcelという仕組みでデータの読み書きを行う - Parcelに読み書きできるのはプリミティブ型、Parcelable、 Serializable、Listのような一部のデータ構造型 アプリ間の遷移をスムーズにする技術 26
  27. 27. #DroidKaigi #room2 /66 Serviceにバインドする - ActivityとServiceがやりとりするにはバインドする必要がある - バインドする方法は以下の3通り バインド方法 プロセスの制約 スレッドの制約 Binderクラスを拡張する 同一プロセス内のみ - メッセンジャーを使用する - すべてのリクエストが1つの スレッドにキューイングされる AIDLを使用する - - アプリ間の遷移をスムーズにする技術 27
  28. 28. #DroidKaigi #room2 /66 AIDLの紹介 - Android インターフェース定義言語 (AIDL) - 文法はJavaのinterfaceの記法に近い - プロセス間通信 (IPC) を行うために用いる手法の1つ - そのままではスレッドセーフではないのでAndroidのドキュメント でも基本的には使わないことを推奨 - とはいえ別プロセス & マルチスレッドでメッセージングを行うため には用いられる https://developer.android.com/guide/components/bound-services アプリ間の遷移をスムーズにする技術 28
  29. 29. #DroidKaigi #room2 /66 AIDLの仕組み アプリ間の遷移をスムーズにする技術 .aidlファイル Stubクラス (abstract) Proxyクラス interface クライアント側用 リモート側用 クラス自動生成 実装 継承 実装クラス 実装 29
  30. 30. #DroidKaigi #room2 /66 AIDLの仕組み アプリ間の遷移をスムーズにする技術 .aidlファイル Stubクラス (abstract) Proxyクラス interface クライアント側用 リモート側用 クラス自動生成 実装 継承 実装クラス 実装 インターフェースを定義 mayLaunchUrl() 30
  31. 31. #DroidKaigi #room2 /66 AIDLの仕組み アプリ間の遷移をスムーズにする技術 .aidlファイル Stubクラス (abstract) Proxyクラス interface クライアント側用 リモート側用 クラス自動生成 実装 継承 実装クラス 実装 mayLaunchUrl()メソッドの 実処理を開発者が実装 31
  32. 32. #DroidKaigi #room2 /66 AIDLの仕組み アプリ間の遷移をスムーズにする技術 .aidlファイル Stubクラス (abstract) Proxyクラス interface クライアント側用 リモート側用 クラス自動生成 実装 継承 実装クラス 継承・実装 mayLaunchUrl()メソッドには プロセス間通信用の処理が実装 32
  33. 33. #DroidKaigi #room2 /66 AIDLの仕組み メソッド呼び出し Parcelに 格納 クライアント側 (例:Activity) リモート側 (例:Service) Proxyクラス binder binder Parcelから 取り出し Stubクラス 実装メソッド呼び出し プロセス間通信 参考:スキルアップのための分散オブジェクト入門 第2回 http://www.atmarkit.co.jp/fjava/rensai2/objetry02/objetry02.html アプリ間の遷移をスムーズにする技術 33
  34. 34. #DroidKaigi #room2 /66 AIDLの仕組み メソッド呼び出し Parcelに 格納 クライアント側 (例:Activity) リモート側 (例:Service) Proxyクラス binder binder Parcelから 取り出し Stubクラス 実装メソッド呼び出し プロセス間通信 アプリ間の遷移をスムーズにする技術 34
  35. 35. #DroidKaigi #room2 /66 AIDLの仕組み メソッド呼び出し Parcelに 格納 クライアント側 (例:Activity) リモート側 (例:Service) Proxyクラス binder binder Parcelから 取り出し Stubクラス 実装メソッド呼び出し プロセス間通信 アプリ間の遷移をスムーズにする技術 mayLaunchUrl() 呼び出し 35
  36. 36. #DroidKaigi #room2 /66 AIDLの仕組み メソッド呼び出し Parcelに 格納 クライアント側 (例:Activity) リモート側 (例:Service) Proxyクラス binder binder Parcelから 取り出し Stubクラス 実装メソッド呼び出し プロセス間通信 アプリ間の遷移をスムーズにする技術 mayLaunchUrl() の実処理を実行 36
  37. 37. #DroidKaigi #room2 /66 余談:シームレスなActivity間の遷移 CustomTabActivity ChromeTabbedActivity任意のアプリ Activityが切り替わっているが JavaScriptの状態などは維持 アプリ間の遷移をスムーズにする技術 37
  38. 38. #DroidKaigi #room2 /66 余談:シームレスなActivity間の遷移 - Custom Tabから通常のChromeの画面への遷移 があまりに自然すぎる - SharedElementは単に新たなViewをアニメー ションさせるだけだが、この遷移ではViewの状 態が完全に引き継がれている アプリ間の遷移をスムーズにする技術 38
  39. 39. #DroidKaigi #room2 /66 状態が保存される遷移の実装 - Viewを含むWebページの状態を保持するオブジェクトをActivity間 で共有 - 生成時のContextは、Application Contextを ContextThemeWrapperに包んだものを使用 - Viewにはほとんど実装を載せず、他のクラスに委譲している アプリ間の遷移をスムーズにする技術 Activity間共有用処理をしている箇所 https://github.com/chromium/chromium/blob/master/chrome/android/java/src /org/chromium/chrome/browser/tab/Tab.java#L1267 39
  40. 40. #DroidKaigi #room2 /66 動的なコンポーネントを提供する技術 40
  41. 41. #DroidKaigi #room2 /66 使い道 - Google Nowのような汎用の情報画面を表示する (端末メーカー向き) - アプリAの一部機能をアプリBでも使いたいが、アプリB側には実装を 持たせたくない場合 動的なコンポーネントを提供する技術 41
  42. 42. #DroidKaigi #room2 /66 Google Nowランチャーの動作を知る - 右の動きは全てランチャーアプリ上での挙動 - 連携のためのコードを除き、ランチャー側に Google Nowの実装は存在しない - ランチャーのコンテンツが右に追い出される動 きはランチャーの実装 動的なコンポーネントを提供する技術 42
  43. 43. #DroidKaigi #room2 /66 Google Nowランチャーの動作を知る - 動作原理さえ知っていればランチャーである必 要もない - ただしGoogle Nowの場合、システムアプリで しか利用できないように制限されている 動的なコンポーネントを提供する技術 43
  44. 44. #DroidKaigi #room2 /66 参考リポジトリの話 - GoogleアプリはOSSではなく、規約上リバースエンジニアリングで 得た情報を発表するわけにはいかないので、同じ動きをするOSSを参 考に話します https://github.com/FabianTerhorst/DrawerOverlayService 動的なコンポーネントを提供する技術 44
  45. 45. #DroidKaigi #room2 /66 Google Nowランチャーの4つのポイント 1. ServiceによってWindowManager#addViewで追加されたViewである 2. 表示するActivityのWindowManager.LayoutParamsを使ってアプリケー ションレイヤに表示させる 3. キーイベントなどに対応するためにWindowクラスのインスタンスを頑張っ て生成している 4. IPCによりランチャー側から指示された位置にViewを表示 動的なコンポーネントを提供する技術 45
  46. 46. #DroidKaigi #room2 /66 WindowManagerについて 右:Facebook Messengerの例 - 一般アプリがWindowManagerを直接使う機会 は多くない - 最も利用するケースは他のアプリの上に常に表 示するとき - 実際にはActivityで表示されるViewなども 全てWindowManagerに追加されることで表示 される 動的なコンポーネントを提供する技術 46
  47. 47. #DroidKaigi #room2 /66 WindowManagerについて - 一般アプリがWindowManagerを直接使う機会 は多くない - 最も利用するケースは他のアプリの上に常に表 示するとき - 実際にはActivityで表示されるViewなども 全てWindowManagerに追加されることで表示 される WindowManager Activity Window setContentView addView 動的なコンポーネントを提供する技術 Windowクラス 最上位のウィンドウの外観と動作ポリシーを定めたクラスで、背景、タイト ル領域、デフォルトのキー処理などの標準的な UIポリシーを提供する 47
  48. 48. #DroidKaigi #room2 /66 WindowManagerについて WindowManager Service - 一般アプリがWindowManagerを直接使う機会 は多くない - 最も利用するケースは他のアプリの上に常に表 示するとき - 実際にはActivityで表示されるViewなども 全てWindowManagerに追加されることで表示 される addView 動的なコンポーネントを提供する技術 48
  49. 49. #DroidKaigi #room2 /6649 Androidの表示レイヤー WALLPAPER 表示内容に合わせて現在33層 のレイヤーに分けられている アプリケーションレイヤ PHONE SYSTEM_ALERT バッテリー不足などの システムアラート APPLICATION_OVERLAY Messengerなどは このレイヤー 電話アプリは通常の アプリより手前に描画 通常のアプリ 壁紙 動的なコンポーネントを提供する技術
  50. 50. #DroidKaigi #room2 /6650 オーバーレイコンテンツの場合 WALLPAPER 他の重要でないアラートなど よりも上に表示される Activityに紐付かない画面の 提供が可能なので、常に画面 上に表示しておくことが可能 アプリケーションレイヤ PHONE SYSTEM_ALERT バッテリー不足などの システムアラート 電話アプリは通常の アプリより手前に描画 通常のアプリ 壁紙 APPLICATION_OVERLAY Messengerなどは このレイヤー ※ このような通知が出てくる 動的なコンポーネントを提供する技術
  51. 51. #DroidKaigi #room2 /6651 Google Nowの場合 WALLPAPER アプリケーションレイヤに表 示する 表示がActivityと紐づくた め、他のアプリの上に表示さ れることはない PHONE SYSTEM_ALERT バッテリー不足などの システムアラート 電話アプリは通常の アプリより手前に描画 壁紙 APPLICATION_OVERLAY Messengerなどは このレイヤー 通常のアプリ アプリケーションレイヤ 動的なコンポーネントを提供する技術
  52. 52. #DroidKaigi #room2 /66 アプリケーションレイヤの制限 - セキュリティ上、任意のServiceが勝手にアプリケーションレイヤ にViewを追加できるべきではない - 対策として、WindowManagerが各ウィンドウごとにtokenを管理し ている - tokenはParcelに書き込める形式になっているので、アプリケー ション側からServiceに渡して制限を回避する 動的なコンポーネントを提供する技術 52
  53. 53. #DroidKaigi #room2 /66 画面の状態変更やボタン操作に対応する Activityではレイアウトに係る処理をWindowクラスで行っているが、 ServiceにはWindowクラスを使う基本的な手段が存在しない WindowManager Activity Window setContentView addView Service addView 動的なコンポーネントを提供する技術 53
  54. 54. #DroidKaigi #room2 /66 System Process Process BProcess A Activity 画面の状態変更やボタン操作に対応する またこれらはそれぞれ別プロセスで動くため、Windowインスタンスを Serviceに渡すなどは不可能 Window Service WindowManager 動的なコンポーネントを提供する技術 54
  55. 55. #DroidKaigi #room2 /66 ServiceでWindowクラスのインスタンス生成 - Windowはabstractクラスで、実装はPhoneWindowクラス - PhoneWindowクラスはinternalクラスなので、直接生成するのは 困難だが頑張って生成する 動的なコンポーネントを提供する技術 55
  56. 56. #DroidKaigi #room2 /66 PhoneWindowのインスタンスを生成できる箇所 動的なコンポーネントを提供する技術 https://search.siprop.org/android-9.0.0_r1.0/search?q=%22new+PhoneWindow%22&def s=&refs=&path=frameworks%2Fbase%2Fcore%2Fjava&hist=&sort=lastmodtime 56
  57. 57. #DroidKaigi #room2 /66 PhoneWindowのインスタンスを生成できる箇所 https://search.siprop.org/android-9.0.0_r1.0/search?q=%22new+PhoneWindow%22&def s=&refs=&path=frameworks%2Fbase%2Fcore%2Fjava&hist=&sort=lastmodtime コンストラクタで生成しており、 getWindow()メソッドで取り出すことも可能 動的なコンポーネントを提供する技術 57
  58. 58. #DroidKaigi #room2 /66 ServiceでWindowクラスのインスタンス生成 - Windowはabstractクラスで、実装はPhoneWindowクラス - PhoneWindowクラスはinternalクラスなので、直接生成するのは 困難だが頑張って生成する Dialogを使って簡単に生成できる val window: Window? = Dialog( context, R.style.Theme_Overlay ).window 動的なコンポーネントを提供する技術 58
  59. 59. #DroidKaigi #room2 /66 ここまでのポイント 1. ServiceによってWindowManager#addViewで追加されたViewである 2. 表示するActivityのレイアウトパラメータを使ってアプリケーションレイ ヤに表示させる 3. 画面回転などリッチな表示に対応するためにWindowインスタンスを頑張っ て生成している 4. IPCによりランチャー側から指示された位置にViewを表示 動的なコンポーネントを提供する技術 59
  60. 60. #DroidKaigi #room2 /6660 ここまでのポイント 1. ServiceによってWindowManager#addViewで追加されたViewである 2. 表示するActivityのレイアウトパラメータを使ってアプリケーションレイ ヤに表示させる 3. 画面回転などリッチな表示に対応するためにWindowインスタンスを頑張っ て生成している 4. IPCによりランチャー側から指示された位置にViewを表示 https://github.com/oboenikui/AppLayerOverlaySample 動的なコンポーネントを提供する技術
  61. 61. #DroidKaigi #room2 /66 ここまでのポイント 1. ServiceによってWindowManager#addViewで追加されたViewである 2. 表示するActivityのレイアウトパラメータを使ってアプリケーションレイ ヤに表示させる 3. 画面回転などリッチな表示に対応するためにWindowインスタンスを頑張っ て生成している 4. IPCによりランチャー側から指示された位置にViewを表示 動的なコンポーネントを提供する技術 61
  62. 62. #DroidKaigi #room2 /66 IPCでランチャーアプリと通信 動的なコンポーネントを提供する技術 ランチャーアプリ 移動すべき座標を通知 62 Google Nowの サービス
  63. 63. #DroidKaigi #room2 /6663 IPCでランチャーアプリと通信 動的なコンポーネントを提供する技術 ランチャーアプリ Google Nowの サービス 移動することを通 知
  64. 64. #DroidKaigi #room2 /66 最終的な実装結果 動的なコンポーネントを提供する技術 簡易的にViewPagerのページめくりと同期させた場 合、右のようになる (参考リポジトリの実行結果) 64
  65. 65. #DroidKaigi #room2 /66 まとめと考察 - Chrome Custom TabsではAIDLによるプロセス間通信を行う - 同様にAIDLで定めたプロトコルをサードパーティに提供し、Activity 起動前の準備を行うことができる - Google Now LauncherもActivityとプロセス間通信を行うこと でアプリケーションレイヤーに描画する - DialogからWindowを生成する手法はAPPLICATION_OVERLAYレイ ヤーでも使えるかも - 「横スワイプで表示」以外も頑張ればできる 65
  66. 66. #DroidKaigi #room2 /66 ご清聴ありがとうございました 66

×