SlideShare a Scribd company logo
1 of 39
1
Hybrid FWs: Cordova/Electron の構造を知る
ソニー株式会社
UXプラットフォーム UX・マーケティング本部 クラウド&サービスアプリ開発運用部門 1部 2 課
関 康治
number of U.S. states state capitols I've visited.
yasuharu.seki.7
ahirun0426
Yasuharu.Seki@jp.sony.com
2
本日の Agenda
Hybrid App を実現する FWs 2つを深掘りしてみる
• 概論
• Hybrid App とは / 特長と課題
• Cordova / Electron 概要
• Cordova の構造を知る
• Cordova Android
• Cordova Android + Crosswalk
• Cordova iOS
• Cordova ubuntu
• Cordova 上で新 Platform に対応するには?
• Electron の構造を知る
• Cordova vs Electron
• 終わりに
3
概論
4
Hybrid App とは ~ もう一つのアプリ実装法 ~
Native Application
の例
UI App
Logic
Driver
Java/Objective-C/C++
Hybrid フレームワーク
JavaScript ・Native 通信用APIを通じてデータをやり取り
・プラグイン機構を用いて機能拡張
WebView
UI App
Logic
Driver
API
Hybrid Application
vs
アプリ組込ブラウザで
WebApp を動かす
ブラウザから
Native Library を
操作可能
5
Hybrid App 特長と課題
特長
- アプリとして利用可能なリソース全てにアクセス可能
- UIの実現が比較的楽 (HTMLでページ作成とNative実装での実現の比較)
- 複数の Platform 間で JavaScript ソースコードの共有が期待できる
課題
- アプリ中で browser を手配する必要がある
- browser は通常 sandbox 化されており、native library を直接操作できるようになっていない
- 必要とする native library が用意されているかどうかは コミュニティ次第
WebView
UI App
Logic
Driver
API
アプリの中で
browser をどのよう
に実現しているか
browser 内部と
外部のnative library とで
どのようにやり取りしている
か
plugin や tool 等の
ecosystem がどの程度
充実しているか
注目すべき点
6
7
とは
• Apache foundation が提供している Hybrid App Framework
• 2009: Nitobi PhoneGap として誕生
• 2011: Adobe が Nitobi を買収 ⇒ Adobe PhoneGap に
• 2011: Apache foundation にコード寄贈 ⇒ Apache Cordova に
• 多くのプラットフォームに対応
• https://cordova.apache.org/contribute/
• 各社の mobile app 開発 Framework の基礎技術として使われている
• IBM MobileFirst Platform (IBM)
• Oracle ADF Mobile (Oracle)
• SAP Mobile Platform (SAP)
• monaca (Asial)
• ionic (Drifty)
8
9
とは
• GitHub.com が提供しているデスクトップ向け Hybrid App Framework
• Atom Editor の下回りとして開発
• 2015.4.17 に Electron という名前でリリース
• Electron を使った desktop アプリ増加中
• Visual Studio Code
• slack desktop app
• wordpress.com desktop app
• etc. etc.
• http://electron.atom.io/
• 動作プラットフォーム
Visual Studio Code
Electron アプリの例
第6回 Apache Cordova 勉強会で Asial 田中さんより紹介がありました
10
の弊社事例
https://first-flight.sony.com/pj/2/HUIS%20REMOTE%20CONTROLLER
HUIS カスタマイズアプリ
Electron を用いて実装
2016.3.28 OSS として公開・開発中
https://github.com/sony/huis-ui-creator
リモコンをあなたらしく。
HUIS[ハウス] REMOTE CONTROLLER
http://huis.jp/
11
Cordova の構造を知る
12
OS (Platform)
WebView
cordova app
構造と設計思想
WebApp (JavaScript)
cordova
JavaScript
library
cordova
Native
library cordova plugin (Native)
cordova plugin (Native)
設計思想: 出来る限り OS(環境)側で用意される機構を用いる
• WebView は OS の物を用いる
• OS 毎に WebView の調達方法が異なる
• Native Layer との通信法は各環境毎に調達
• かなり Hack に近いことをしている
JS⇔Native の通信方法は
Cordova で用意。(かなりHack)
WebView の実現法は
target platform 毎に異なる
Platform
Cordova
Application
注目
13
WebView
cordova app
JS ⇔ Native 通信のフロー
WebApp (JavaScript) cordova JS lib cordova native lib
cordova plugin (Native)
cordova plugin (Native)
アクション
JS ⇒ Native 通信
Native ⇒ JS 通信
結果通知
CordovaAPI
cordova.exec()
処理終了callback
CordovapluginAPI
plugin 呼び出し
処理終了通知
互いに独立互いに独立
アプリ開発者は Cordova API と
Cordova plugin API のみ知ってい
れば良い
plugin
処理
callbackとなる
関数objectを保持する
呼出状態保持するかは
PF毎の実装次第
14
plugin の例
• WebApp(JavaScript)からpluginを呼び出すコード
• Platform 問わず共通
• plugin内でJavaScriptから呼び出される部分のコード
• Platform 毎にAPIが違う
• Android (Java) の場合の例
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
// functionA
if (action.equals("actionA")) {
int int_value = args.getInt(0);
this.actionA(int_value, callbackContext);
return true;
}
// functionB
else if (action.equals("actionB")) {
this.actionB(callbackContext);
return true;
}
return false;
}
cordova.exec( win_callback, fail_callback, "service名", "action名", [引数の配列] );
WebView
cordova app
WebApp
plugin
plugin
Cordova
15
16
cordova native lib
Android Platform の構成
MainActivity extends CordovaActivity
SystemWebViewEngine
implements CordovaWebViewEngine android.webkit.WebViewを継承
WebView: Android OS に付随の android.webkit.WebView を用いる
1. MainActivity 起動
2. SystemWebViewEngine, SystemWebView を作成
3. cordova native lib を生成
4. _cordovaNative オブジェクトを addJavaScriptInterface() で JS engine に登録
5. WebApp 起動
6. cordova JS library 初期化
SystemWebView extends WebView
WebApp (JavaScript)
cordova
JS
library
_cordovaNative
webView.addJavaScriptInterface() で登録
OS Version 毎に挙動が異なる
アプリのファイルサイズは小さい
17
JS_OBJECT形式
_cordovaNative を通じて通信
• 起動時に登録された _cordovaNative の exec() を実行するこ
とで、Java層の CordovaBridge.jsExec が呼び出される
• 登録には addJavaScriptInterface() を利用
cordova native lib
Android Platform: JS ⇒ Native 通信法
WebView
cordova JS library
_cordovaNative
PROMPT形式
window.prompt() ⇒
WebChromeClient.onJsPrompt() を利用
• JS層で window.prompt() を実行すると、Chrome のイベント
として onJsPrompt() が呼び出される
• onJsPrompt() に渡されてきたメッセージを cordova native lib
がよしなに判断 ⇒ plugin コールする
cordova native lib
WebView
cordova JS library
_cordovaNative
prompt()
onJsPrompt()
通常は JS_OBJECT形式
fallback として PROMPT 形式を使う
18
Android Platform: Native ⇒ JS 通信法
POLLING形式
50ms 毎に問い合わせ
• JS側libが50ms毎にretrieveJsMessages()
を実行してNative側のmessage queueの
内容を確認
• 確認には JS ⇒ Native の通信法を用いる
LOAD_URL形式
webView.loadUrl() で JS 実行
• Native側でcallbackFromNative() を呼び出
す JS コードを生成
• loadUrl() のURL 引数に 'JavaScript: [コー
ド]' を渡して実行
ONLINE_EVENT形式
online/offline イベントで通知
• ネットワーク online/offline 状態の切り替
え
• WebView.setNetworkAvailable() を使う
• JS側で online と offline イベントに
listener を仕掛けておく
• イベントが到着したら messsage queue
の内容を確認
• 確認には JS ⇒ Native の通信法を用いる
cordova native lib
WebView
cordova JS library
message queue
resultresultresult
…
check
check
check
…
cordova native lib
WebView
cordova JS library
result
…
callbackFromNative()
loadUrl()
cordova native lib
WebView
cordova JS library
result
online状
態切替
online event
event listener
check
デフォルトは ONLINE_EVENT 形式
JS側で cordova.setNativeToJsBridgeMode() を使って変更可能
19
20
21
とは
OS の WebView の代わりに、アプリに組み込んだ Chromium をブラウザとして利用する
・OSに拠らず最新の API が利用可能
・動作確認の対象が Crosswalk のみに絞れる
・アプリの配布ファイルサイズが ~20MB 位増加する
OS (Platform)
WebView
cordova app
WebApp (JavaScript)
cordova
JavaScript
library
cordova
Native
library cordova plugin
cordova plugin
OS (Platform)
cordova app
cordova plugin
cordova plugin
Crosswalk
WebApp (JavaScript)
cordova
JavaScript
library
cordova
Native
library
22
cordova native lib
Android Platform の構成
MainActivity extends CordovaActivity
SystemWebViewEngine
implements CordovaWebViewEngine android.webkit.WebViewを継承
WebView: Android OS に付随の android.webkit.WebView を用いる
1. MainActivity 起動
2. SystemWebViewEngine, SystemWebView を作成
3. cordova native lib を生成
4. _cordovaNative オブジェクトを addJavaScriptInterface() で JS engine に登録
5. WebApp 起動
6. cordova JS library 初期化
SystemWebView extends WebView
WebApp (JavaScript)
cordova
JS
library
_cordovaNative
webView.addJavaScriptInterface() で登録
23
cordova native lib
Android + Crosswalk の構成
MainActivity extends CordovaActivity
XWalkWebViewEngine
implements CordovaWebViewEngine ChromiumのWebViewを継承
WebView: Crosswalk に包含された Chromium の WebView を用いる
1. MainActivity 起動
2. SystemWebViewEngine, SystemWebView を作成
3. cordova native lib を生成
4. _cordovaNative オブジェクトを addJavaScriptInterface() で JS engine に登録
5. WebApp 起動
6. cordova JS library 初期化
XWalkCordovaView extends XWalkView
WebApp (JavaScript)
cordova
JS
library
_cordovaNative
webView.addJavaScriptInterface() で登録
通常の Android 版と同じ動作
• 初期化
• JS ⇔ Native 通信
24
25
cordova native library
iOS Platform の構成
AppDelegate
CDVViewController : UIWebViewDelegate
WebView: iOS に付属の UIWebView を利用
1. AppDelegate 起動
2. (アプリ実装) CDVViewController を継承した ViewController を作成
3. AppDelegate.viewController に作成した ViewController を登録
4. viewDidLoad で config.xml に記述してある WebApp 起動ファイルを読み込む
5. cordova JS library 初期化
WebApp (JavaScript)
cordova
JS
library
iOS
API
* CDVViewController に iOS API コールされた際のフックが内蔵されている
cordova-ios 4.0 から iOS8,9 向けに
WKWebView が利用可能
⇒ cordova-plugin-wkwebview-engine を追加インストール
26
stringByEvaluatingJavaScriptFromString形式
UIWebKit 標準の Native ⇒ JS 実行法で通信
• cordova JS library をコールするJavaScriptコードを native lib で生成
• webview:stringByEvaluatingJavaScriptFromString: を利用して生成したコードを
WebView で実行
cordova native lib
iOS Platform: Native ⇒ JS 通信法
WebView
cordova JS library
WKWebView では
evaluateJavaScript:completionHandler:
27
iOS Platform: JS ⇒ Native 通信法
IFRAME形式
iframe にURL読み込むことで通知
• キューにコマンドをプール
• WebView 内の iframe にダミーページを
読み込む
• native lib がページ読み込みトリガをフッ
ク
• Native側からJS側にのキューを読み込む
XHR形式
XMLHTTPRequest()発行で通知
• キューにコマンドをプール
• native lib が httpd として動作
• XMLHTTPRequest() をローカルで実行
• httpd が XHR をフック
• Native側からJS側のキューを読み込む
WKWebKit形式
標準の JS⇒Native通信
• window.webkit.messageHandlers を用い
て native のライブラリをコールcordova native lib
WebView
cordova JS library
command queue
…
load
page
cordova native lib
WebView
cordova JS library
message
Handlers
iframe
通知
check
command
command
command
cordova native lib
WebView
cordova JS library
command queue
…
XMLHTTPRequest()
check
command
command
command
デフォルトは IFRAME 形式
WKWebKit が使える場合は WKWebKit 方式
WKWebKit は iOS 8,9 のみの対応
& 要 webview engine plugin 追加
28
29
cordova native library
ubuntu Platform の構成
QQmlApplicationEngine
WebContext (com.canonical.Oxide)
WebView: Qtのライブラリ com.canonical.Oxide を使用
• Chromium ベースの WebView をQtで扱えるようにしたもの
• ubuntu 提供元である Canonical Ltd. が作成
• cordova ubuntu も canonical がメインコントリビュータ
• 主に ubuntu OS (phone用) 向けに提供している
Native 通信法:Oxide の Message API を用いる
• window.oxide.sendMessage() を実行することで JS ⇒ Native 呼び出し可能
• webView.rootFrame.sendMessage() を実行することで Native ⇒ JS 呼び出し可能
WebApp (JavaScript)
cordova
JS
library
Oxide
Message API
CordovaViewInternal
30
31
他 PF に移植する場合の作業
WebView を提供するブラウザの調達
1. OS/Platform/Framework に標準のブラウザを採用
• インストーラのファイルサイズが小さくなる
• OS等のバリエーション毎に動作が異なる可能性がある (検証・修正工数の増大)
2. 調達したブラウザをアプリに結合する
• ブラウザの挙動が固定できる
• JS⇔Native通信法の選択肢が比較的広い
• インストーラフットプリントの大型化
• ブラウザバージョンアップへの追従工数が必要
JavaScript⇔Native の通信法を確保
• 正規の方法があればそれを採用
• Hack での通信法確保が必要になる場合も
その他
• 使用したい plugin を移植する必要あり
• Cordova CLI へ platform 追加したい場合は cordova project へ upstream する必要あり
32
Electron の構造を知る
33
Electron
構造と設計思想
Chromium
Node plugin
(Native)
設計思想: WebView (Chromium) と node をアプリに組み込んでしまう
• WebView は組み込まれた Chromium の物を利用する
• Native Layer とのやり取りは node が受け持つ
• WebView と node 間のやり取りは Chromium の IPC 機能を利用する
Chromium
Electron
Application
node
WebView
v8 v8
node.js
Node plugin
(Native)
WebApp
(Browser part)
Chromium
IPC
Blink
WebApp
(Renderer part)
34
embedded Linux にもいける!?
アプリ作成法
=
35
課題
Electron の課題
• Electron の開発はほぼ1人の肩に掛かっている (zcbenz)
• リソースも足りていない状況
• Chromium/node を抱え込んでいる
• 配布ファイルサイズが大きくなってしまう (~20MB位)
• Chromium 以外のブラウザを利用したい場合の対応は難しい
• 最新の Chromium/node Update 反映にタイムラグがある
Cordova/Electron 両対応 Hybrid App を開発する際の課題
• Cordova / Electron では、WebAppの構成が異なる
• アプリコードの使い回しをする際にはハードルになりそう
36
Cordova と Electron
37
Cordova vs Electron 比較
開発者 Apache Foundation GitHub.com (@zcbenz)
ターゲットアプリ (原則) モバイルアプリ デスクトップアプリ
PF Android, iOS, Ubuntu, Windows desktop,
browser
Amazon Fire OS, Blackberry, FireFox OS, Mac OS X, Web OS, Windows
phone 8
Windows, Mac OS X, Linux
WebView (原則) OS付随のブラウザを使用 内包する Chromium を使用
WebApp構成 ソリッド スレッドが明示的に
Browser(main)/Renderer(UI) で分かれてい
る
plugin cordova plugin (Cordova が提供する API) node module (node が提供)
plugin repository npm (ecosystem:cordova) n/a
38
終わりに
39
終わりに
現況で Hybrid アプリケーションを実現する場合に使える、2つの代表的な
FWs の構造を確認してみた。
それぞれの構成を大まかに理解できたのであれば嬉しい。
ご清聴ありがとうございました

More Related Content

What's hot

シリコンバレーでエンジニア就職する前に知りたかったこと
シリコンバレーでエンジニア就職する前に知りたかったことシリコンバレーでエンジニア就職する前に知りたかったこと
シリコンバレーでエンジニア就職する前に知りたかったことTatsuya Nanjo
 
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)Amazon Web Services Japan
 
[AWSマイスターシリーズ] AWS CloudFormation
[AWSマイスターシリーズ] AWS CloudFormation[AWSマイスターシリーズ] AWS CloudFormation
[AWSマイスターシリーズ] AWS CloudFormationAmazon Web Services Japan
 
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~Hiroki Tateno
 
re:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみた
re:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみたre:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみた
re:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみたHideaki Aoyagi
 
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみようrsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみようKen Sawada
 
アクセスプラン(実行計画)の読み方入門
アクセスプラン(実行計画)の読み方入門アクセスプラン(実行計画)の読み方入門
アクセスプラン(実行計画)の読み方入門Akira Shimosako
 
MongoDB on AWSクラウドという選択
MongoDB on AWSクラウドという選択MongoDB on AWSクラウドという選択
MongoDB on AWSクラウドという選択Yasuhiro Matsuo
 
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方Hiroshi Tokumaru
 
「Azure durable functions」の概要
「Azure durable functions」の概要「Azure durable functions」の概要
「Azure durable functions」の概要裕之 木下
 
Panamaを先取り!? JVMCIでJITと遊ぶ
Panamaを先取り!? JVMCIでJITと遊ぶPanamaを先取り!? JVMCIでJITと遊ぶ
Panamaを先取り!? JVMCIでJITと遊ぶYasumasa Suenaga
 
20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation 20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation Amazon Web Services Japan
 
AWSでのバースト ― GP2 T2 ご紹介資料
AWSでのバースト ― GP2 T2 ご紹介資料AWSでのバースト ― GP2 T2 ご紹介資料
AWSでのバースト ― GP2 T2 ご紹介資料Rasmus Ekman
 
ReDos検出プログラムの作成とOSSへの適用 #seccamp
ReDos検出プログラムの作成とOSSへの適用 #seccampReDos検出プログラムの作成とOSSへの適用 #seccamp
ReDos検出プログラムの作成とOSSへの適用 #seccampYujiro Yahata
 
20210526 AWS Expert Online マルチアカウント管理の基本
20210526 AWS Expert Online マルチアカウント管理の基本20210526 AWS Expert Online マルチアカウント管理の基本
20210526 AWS Expert Online マルチアカウント管理の基本Amazon Web Services Japan
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方Recruit Lifestyle Co., Ltd.
 

What's hot (20)

シリコンバレーでエンジニア就職する前に知りたかったこと
シリコンバレーでエンジニア就職する前に知りたかったことシリコンバレーでエンジニア就職する前に知りたかったこと
シリコンバレーでエンジニア就職する前に知りたかったこと
 
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
[AWSマイスターシリーズ]Amazon Elastic Load Balancing (ELB)
 
[AWSマイスターシリーズ] AWS CloudFormation
[AWSマイスターシリーズ] AWS CloudFormation[AWSマイスターシリーズ] AWS CloudFormation
[AWSマイスターシリーズ] AWS CloudFormation
 
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
 
今だからこそ見直そうAzureコスト最適化
今だからこそ見直そうAzureコスト最適化今だからこそ見直そうAzureコスト最適化
今だからこそ見直そうAzureコスト最適化
 
re:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみた
re:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみたre:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみた
re:Invent 2021のS3アップデート紹介 & Glacier Instant Retrieval試してみた
 
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみようrsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
 
アクセスプラン(実行計画)の読み方入門
アクセスプラン(実行計画)の読み方入門アクセスプラン(実行計画)の読み方入門
アクセスプラン(実行計画)の読み方入門
 
Azure Search 大全
Azure Search 大全Azure Search 大全
Azure Search 大全
 
MongoDB on AWSクラウドという選択
MongoDB on AWSクラウドという選択MongoDB on AWSクラウドという選択
MongoDB on AWSクラウドという選択
 
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
SSRF対策としてAmazonから発表されたIMDSv2の効果と破り方
 
「Azure durable functions」の概要
「Azure durable functions」の概要「Azure durable functions」の概要
「Azure durable functions」の概要
 
AWS Blackbelt 2015シリーズ RDS
AWS Blackbelt 2015シリーズ RDSAWS Blackbelt 2015シリーズ RDS
AWS Blackbelt 2015シリーズ RDS
 
Panamaを先取り!? JVMCIでJITと遊ぶ
Panamaを先取り!? JVMCIでJITと遊ぶPanamaを先取り!? JVMCIでJITと遊ぶ
Panamaを先取り!? JVMCIでJITと遊ぶ
 
20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation 20200826 AWS Black Belt Online Seminar AWS CloudFormation
20200826 AWS Black Belt Online Seminar AWS CloudFormation
 
AWSでのバースト ― GP2 T2 ご紹介資料
AWSでのバースト ― GP2 T2 ご紹介資料AWSでのバースト ― GP2 T2 ご紹介資料
AWSでのバースト ― GP2 T2 ご紹介資料
 
ReDos検出プログラムの作成とOSSへの適用 #seccamp
ReDos検出プログラムの作成とOSSへの適用 #seccampReDos検出プログラムの作成とOSSへの適用 #seccamp
ReDos検出プログラムの作成とOSSへの適用 #seccamp
 
20210526 AWS Expert Online マルチアカウント管理の基本
20210526 AWS Expert Online マルチアカウント管理の基本20210526 AWS Expert Online マルチアカウント管理の基本
20210526 AWS Expert Online マルチアカウント管理の基本
 
AWS BlackBelt AWS上でのDDoS対策
AWS BlackBelt AWS上でのDDoS対策AWS BlackBelt AWS上でのDDoS対策
AWS BlackBelt AWS上でのDDoS対策
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方
 

Similar to cordova/electronの構造を知る

2016/05/01 Visual Studio with Cordova
2016/05/01 Visual Studio with Cordova2016/05/01 Visual Studio with Cordova
2016/05/01 Visual Studio with Cordovamiso- soup3
 
Visual Studio 2015 を使用した Cordova アプリの開発
Visual Studio 2015 を使用した Cordova アプリの開発Visual Studio 2015 を使用した Cordova アプリの開発
Visual Studio 2015 を使用した Cordova アプリの開発Osamu Monoe
 
実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~
実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~
実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~Saki Homma
 
VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発Yuta Matsumura
 
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-Saki Homma
 
ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜
ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜
ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜Kensaku Komatsu
 
Cordovaの最近ホットな話題と地雷をまとめて紹介
Cordovaの最近ホットな話題と地雷をまとめて紹介Cordovaの最近ホットな話題と地雷をまとめて紹介
Cordovaの最近ホットな話題と地雷をまとめて紹介アシアル株式会社
 
WebSocket + Node.jsでつくるチャットアプリ
WebSocket + Node.jsでつくるチャットアプリWebSocket + Node.jsでつくるチャットアプリ
WebSocket + Node.jsでつくるチャットアプリKohei Kadowaki
 
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフラインWebフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフラインShumpei Shiraishi
 
Monacaでつくるハイブリッドアプリ
MonacaでつくるハイブリッドアプリMonacaでつくるハイブリッドアプリ
MonacaでつくるハイブリッドアプリMonaca
 
PhoneGapでWebアプリをスマホアプリ化
PhoneGapでWebアプリをスマホアプリ化PhoneGapでWebアプリをスマホアプリ化
PhoneGapでWebアプリをスマホアプリ化Takashi Okamoto
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますfukuoka.ex
 
[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介
[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介
[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介david9142
 
Phone gap+javascriptスマホアプリ開発(入門編)
Phone gap+javascriptスマホアプリ開発(入門編)Phone gap+javascriptスマホアプリ開発(入門編)
Phone gap+javascriptスマホアプリ開発(入門編)Monaca
 
Isomorphic web development with scala and scala.js
Isomorphic web development  with scala and scala.jsIsomorphic web development  with scala and scala.js
Isomorphic web development with scala and scala.jsTanUkkii
 
20200516 selenium-meetup-winappdriver
20200516 selenium-meetup-winappdriver20200516 selenium-meetup-winappdriver
20200516 selenium-meetup-winappdriverHiroko Tamagawa
 
WKWebViewとUIWebView
WKWebViewとUIWebViewWKWebViewとUIWebView
WKWebViewとUIWebViewYuki Hirai
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」fukuoka.ex
 

Similar to cordova/electronの構造を知る (20)

2016/05/01 Visual Studio with Cordova
2016/05/01 Visual Studio with Cordova2016/05/01 Visual Studio with Cordova
2016/05/01 Visual Studio with Cordova
 
Visual Studio 2015 を使用した Cordova アプリの開発
Visual Studio 2015 を使用した Cordova アプリの開発Visual Studio 2015 を使用した Cordova アプリの開発
Visual Studio 2015 を使用した Cordova アプリの開発
 
実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~
実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~
実践 Web App for Containers! ~コンテナ開発の基礎からDevOps環境の構築まで~
 
VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発VSCodeで始めるAzure Static Web Apps開発
VSCodeで始めるAzure Static Web Apps開発
 
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
 
ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜
ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜
ブラウザからWeb OSへ〜Web - TV連携事例からその可能性を探る〜
 
Cordovaの最近ホットな話題と地雷をまとめて紹介
Cordovaの最近ホットな話題と地雷をまとめて紹介Cordovaの最近ホットな話題と地雷をまとめて紹介
Cordovaの最近ホットな話題と地雷をまとめて紹介
 
WebSocket + Node.jsでつくるチャットアプリ
WebSocket + Node.jsでつくるチャットアプリWebSocket + Node.jsでつくるチャットアプリ
WebSocket + Node.jsでつくるチャットアプリ
 
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフラインWebフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
 
Monacaでつくるハイブリッドアプリ
MonacaでつくるハイブリッドアプリMonacaでつくるハイブリッドアプリ
Monacaでつくるハイブリッドアプリ
 
PhoneGapでWebアプリをスマホアプリ化
PhoneGapでWebアプリをスマホアプリ化PhoneGapでWebアプリをスマホアプリ化
PhoneGapでWebアプリをスマホアプリ化
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
 
[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介
[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介
[公開用]Netラボ2012年2月勉強会 asp.netmvc4 beta新機能の紹介
 
Phone gap+javascriptスマホアプリ開発(入門編)
Phone gap+javascriptスマホアプリ開発(入門編)Phone gap+javascriptスマホアプリ開発(入門編)
Phone gap+javascriptスマホアプリ開発(入門編)
 
Isomorphic web development with scala and scala.js
Isomorphic web development  with scala and scala.jsIsomorphic web development  with scala and scala.js
Isomorphic web development with scala and scala.js
 
SocketStream入門
SocketStream入門SocketStream入門
SocketStream入門
 
Mobile Web
Mobile WebMobile Web
Mobile Web
 
20200516 selenium-meetup-winappdriver
20200516 selenium-meetup-winappdriver20200516 selenium-meetup-winappdriver
20200516 selenium-meetup-winappdriver
 
WKWebViewとUIWebView
WKWebViewとUIWebViewWKWebViewとUIWebView
WKWebViewとUIWebView
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
 

cordova/electronの構造を知る

  • 1. 1 Hybrid FWs: Cordova/Electron の構造を知る ソニー株式会社 UXプラットフォーム UX・マーケティング本部 クラウド&サービスアプリ開発運用部門 1部 2 課 関 康治 number of U.S. states state capitols I've visited. yasuharu.seki.7 ahirun0426 Yasuharu.Seki@jp.sony.com
  • 2. 2 本日の Agenda Hybrid App を実現する FWs 2つを深掘りしてみる • 概論 • Hybrid App とは / 特長と課題 • Cordova / Electron 概要 • Cordova の構造を知る • Cordova Android • Cordova Android + Crosswalk • Cordova iOS • Cordova ubuntu • Cordova 上で新 Platform に対応するには? • Electron の構造を知る • Cordova vs Electron • 終わりに
  • 4. 4 Hybrid App とは ~ もう一つのアプリ実装法 ~ Native Application の例 UI App Logic Driver Java/Objective-C/C++ Hybrid フレームワーク JavaScript ・Native 通信用APIを通じてデータをやり取り ・プラグイン機構を用いて機能拡張 WebView UI App Logic Driver API Hybrid Application vs アプリ組込ブラウザで WebApp を動かす ブラウザから Native Library を 操作可能
  • 5. 5 Hybrid App 特長と課題 特長 - アプリとして利用可能なリソース全てにアクセス可能 - UIの実現が比較的楽 (HTMLでページ作成とNative実装での実現の比較) - 複数の Platform 間で JavaScript ソースコードの共有が期待できる 課題 - アプリ中で browser を手配する必要がある - browser は通常 sandbox 化されており、native library を直接操作できるようになっていない - 必要とする native library が用意されているかどうかは コミュニティ次第 WebView UI App Logic Driver API アプリの中で browser をどのよう に実現しているか browser 内部と 外部のnative library とで どのようにやり取りしている か plugin や tool 等の ecosystem がどの程度 充実しているか 注目すべき点
  • 6. 6
  • 7. 7 とは • Apache foundation が提供している Hybrid App Framework • 2009: Nitobi PhoneGap として誕生 • 2011: Adobe が Nitobi を買収 ⇒ Adobe PhoneGap に • 2011: Apache foundation にコード寄贈 ⇒ Apache Cordova に • 多くのプラットフォームに対応 • https://cordova.apache.org/contribute/ • 各社の mobile app 開発 Framework の基礎技術として使われている • IBM MobileFirst Platform (IBM) • Oracle ADF Mobile (Oracle) • SAP Mobile Platform (SAP) • monaca (Asial) • ionic (Drifty)
  • 8. 8
  • 9. 9 とは • GitHub.com が提供しているデスクトップ向け Hybrid App Framework • Atom Editor の下回りとして開発 • 2015.4.17 に Electron という名前でリリース • Electron を使った desktop アプリ増加中 • Visual Studio Code • slack desktop app • wordpress.com desktop app • etc. etc. • http://electron.atom.io/ • 動作プラットフォーム Visual Studio Code Electron アプリの例 第6回 Apache Cordova 勉強会で Asial 田中さんより紹介がありました
  • 10. 10 の弊社事例 https://first-flight.sony.com/pj/2/HUIS%20REMOTE%20CONTROLLER HUIS カスタマイズアプリ Electron を用いて実装 2016.3.28 OSS として公開・開発中 https://github.com/sony/huis-ui-creator リモコンをあなたらしく。 HUIS[ハウス] REMOTE CONTROLLER http://huis.jp/
  • 12. 12 OS (Platform) WebView cordova app 構造と設計思想 WebApp (JavaScript) cordova JavaScript library cordova Native library cordova plugin (Native) cordova plugin (Native) 設計思想: 出来る限り OS(環境)側で用意される機構を用いる • WebView は OS の物を用いる • OS 毎に WebView の調達方法が異なる • Native Layer との通信法は各環境毎に調達 • かなり Hack に近いことをしている JS⇔Native の通信方法は Cordova で用意。(かなりHack) WebView の実現法は target platform 毎に異なる Platform Cordova Application 注目
  • 13. 13 WebView cordova app JS ⇔ Native 通信のフロー WebApp (JavaScript) cordova JS lib cordova native lib cordova plugin (Native) cordova plugin (Native) アクション JS ⇒ Native 通信 Native ⇒ JS 通信 結果通知 CordovaAPI cordova.exec() 処理終了callback CordovapluginAPI plugin 呼び出し 処理終了通知 互いに独立互いに独立 アプリ開発者は Cordova API と Cordova plugin API のみ知ってい れば良い plugin 処理 callbackとなる 関数objectを保持する 呼出状態保持するかは PF毎の実装次第
  • 14. 14 plugin の例 • WebApp(JavaScript)からpluginを呼び出すコード • Platform 問わず共通 • plugin内でJavaScriptから呼び出される部分のコード • Platform 毎にAPIが違う • Android (Java) の場合の例 public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { // functionA if (action.equals("actionA")) { int int_value = args.getInt(0); this.actionA(int_value, callbackContext); return true; } // functionB else if (action.equals("actionB")) { this.actionB(callbackContext); return true; } return false; } cordova.exec( win_callback, fail_callback, "service名", "action名", [引数の配列] ); WebView cordova app WebApp plugin plugin Cordova
  • 15. 15
  • 16. 16 cordova native lib Android Platform の構成 MainActivity extends CordovaActivity SystemWebViewEngine implements CordovaWebViewEngine android.webkit.WebViewを継承 WebView: Android OS に付随の android.webkit.WebView を用いる 1. MainActivity 起動 2. SystemWebViewEngine, SystemWebView を作成 3. cordova native lib を生成 4. _cordovaNative オブジェクトを addJavaScriptInterface() で JS engine に登録 5. WebApp 起動 6. cordova JS library 初期化 SystemWebView extends WebView WebApp (JavaScript) cordova JS library _cordovaNative webView.addJavaScriptInterface() で登録 OS Version 毎に挙動が異なる アプリのファイルサイズは小さい
  • 17. 17 JS_OBJECT形式 _cordovaNative を通じて通信 • 起動時に登録された _cordovaNative の exec() を実行するこ とで、Java層の CordovaBridge.jsExec が呼び出される • 登録には addJavaScriptInterface() を利用 cordova native lib Android Platform: JS ⇒ Native 通信法 WebView cordova JS library _cordovaNative PROMPT形式 window.prompt() ⇒ WebChromeClient.onJsPrompt() を利用 • JS層で window.prompt() を実行すると、Chrome のイベント として onJsPrompt() が呼び出される • onJsPrompt() に渡されてきたメッセージを cordova native lib がよしなに判断 ⇒ plugin コールする cordova native lib WebView cordova JS library _cordovaNative prompt() onJsPrompt() 通常は JS_OBJECT形式 fallback として PROMPT 形式を使う
  • 18. 18 Android Platform: Native ⇒ JS 通信法 POLLING形式 50ms 毎に問い合わせ • JS側libが50ms毎にretrieveJsMessages() を実行してNative側のmessage queueの 内容を確認 • 確認には JS ⇒ Native の通信法を用いる LOAD_URL形式 webView.loadUrl() で JS 実行 • Native側でcallbackFromNative() を呼び出 す JS コードを生成 • loadUrl() のURL 引数に 'JavaScript: [コー ド]' を渡して実行 ONLINE_EVENT形式 online/offline イベントで通知 • ネットワーク online/offline 状態の切り替 え • WebView.setNetworkAvailable() を使う • JS側で online と offline イベントに listener を仕掛けておく • イベントが到着したら messsage queue の内容を確認 • 確認には JS ⇒ Native の通信法を用いる cordova native lib WebView cordova JS library message queue resultresultresult … check check check … cordova native lib WebView cordova JS library result … callbackFromNative() loadUrl() cordova native lib WebView cordova JS library result online状 態切替 online event event listener check デフォルトは ONLINE_EVENT 形式 JS側で cordova.setNativeToJsBridgeMode() を使って変更可能
  • 19. 19
  • 20. 20
  • 21. 21 とは OS の WebView の代わりに、アプリに組み込んだ Chromium をブラウザとして利用する ・OSに拠らず最新の API が利用可能 ・動作確認の対象が Crosswalk のみに絞れる ・アプリの配布ファイルサイズが ~20MB 位増加する OS (Platform) WebView cordova app WebApp (JavaScript) cordova JavaScript library cordova Native library cordova plugin cordova plugin OS (Platform) cordova app cordova plugin cordova plugin Crosswalk WebApp (JavaScript) cordova JavaScript library cordova Native library
  • 22. 22 cordova native lib Android Platform の構成 MainActivity extends CordovaActivity SystemWebViewEngine implements CordovaWebViewEngine android.webkit.WebViewを継承 WebView: Android OS に付随の android.webkit.WebView を用いる 1. MainActivity 起動 2. SystemWebViewEngine, SystemWebView を作成 3. cordova native lib を生成 4. _cordovaNative オブジェクトを addJavaScriptInterface() で JS engine に登録 5. WebApp 起動 6. cordova JS library 初期化 SystemWebView extends WebView WebApp (JavaScript) cordova JS library _cordovaNative webView.addJavaScriptInterface() で登録
  • 23. 23 cordova native lib Android + Crosswalk の構成 MainActivity extends CordovaActivity XWalkWebViewEngine implements CordovaWebViewEngine ChromiumのWebViewを継承 WebView: Crosswalk に包含された Chromium の WebView を用いる 1. MainActivity 起動 2. SystemWebViewEngine, SystemWebView を作成 3. cordova native lib を生成 4. _cordovaNative オブジェクトを addJavaScriptInterface() で JS engine に登録 5. WebApp 起動 6. cordova JS library 初期化 XWalkCordovaView extends XWalkView WebApp (JavaScript) cordova JS library _cordovaNative webView.addJavaScriptInterface() で登録 通常の Android 版と同じ動作 • 初期化 • JS ⇔ Native 通信
  • 24. 24
  • 25. 25 cordova native library iOS Platform の構成 AppDelegate CDVViewController : UIWebViewDelegate WebView: iOS に付属の UIWebView を利用 1. AppDelegate 起動 2. (アプリ実装) CDVViewController を継承した ViewController を作成 3. AppDelegate.viewController に作成した ViewController を登録 4. viewDidLoad で config.xml に記述してある WebApp 起動ファイルを読み込む 5. cordova JS library 初期化 WebApp (JavaScript) cordova JS library iOS API * CDVViewController に iOS API コールされた際のフックが内蔵されている cordova-ios 4.0 から iOS8,9 向けに WKWebView が利用可能 ⇒ cordova-plugin-wkwebview-engine を追加インストール
  • 26. 26 stringByEvaluatingJavaScriptFromString形式 UIWebKit 標準の Native ⇒ JS 実行法で通信 • cordova JS library をコールするJavaScriptコードを native lib で生成 • webview:stringByEvaluatingJavaScriptFromString: を利用して生成したコードを WebView で実行 cordova native lib iOS Platform: Native ⇒ JS 通信法 WebView cordova JS library WKWebView では evaluateJavaScript:completionHandler:
  • 27. 27 iOS Platform: JS ⇒ Native 通信法 IFRAME形式 iframe にURL読み込むことで通知 • キューにコマンドをプール • WebView 内の iframe にダミーページを 読み込む • native lib がページ読み込みトリガをフッ ク • Native側からJS側にのキューを読み込む XHR形式 XMLHTTPRequest()発行で通知 • キューにコマンドをプール • native lib が httpd として動作 • XMLHTTPRequest() をローカルで実行 • httpd が XHR をフック • Native側からJS側のキューを読み込む WKWebKit形式 標準の JS⇒Native通信 • window.webkit.messageHandlers を用い て native のライブラリをコールcordova native lib WebView cordova JS library command queue … load page cordova native lib WebView cordova JS library message Handlers iframe 通知 check command command command cordova native lib WebView cordova JS library command queue … XMLHTTPRequest() check command command command デフォルトは IFRAME 形式 WKWebKit が使える場合は WKWebKit 方式 WKWebKit は iOS 8,9 のみの対応 & 要 webview engine plugin 追加
  • 28. 28
  • 29. 29 cordova native library ubuntu Platform の構成 QQmlApplicationEngine WebContext (com.canonical.Oxide) WebView: Qtのライブラリ com.canonical.Oxide を使用 • Chromium ベースの WebView をQtで扱えるようにしたもの • ubuntu 提供元である Canonical Ltd. が作成 • cordova ubuntu も canonical がメインコントリビュータ • 主に ubuntu OS (phone用) 向けに提供している Native 通信法:Oxide の Message API を用いる • window.oxide.sendMessage() を実行することで JS ⇒ Native 呼び出し可能 • webView.rootFrame.sendMessage() を実行することで Native ⇒ JS 呼び出し可能 WebApp (JavaScript) cordova JS library Oxide Message API CordovaViewInternal
  • 30. 30
  • 31. 31 他 PF に移植する場合の作業 WebView を提供するブラウザの調達 1. OS/Platform/Framework に標準のブラウザを採用 • インストーラのファイルサイズが小さくなる • OS等のバリエーション毎に動作が異なる可能性がある (検証・修正工数の増大) 2. 調達したブラウザをアプリに結合する • ブラウザの挙動が固定できる • JS⇔Native通信法の選択肢が比較的広い • インストーラフットプリントの大型化 • ブラウザバージョンアップへの追従工数が必要 JavaScript⇔Native の通信法を確保 • 正規の方法があればそれを採用 • Hack での通信法確保が必要になる場合も その他 • 使用したい plugin を移植する必要あり • Cordova CLI へ platform 追加したい場合は cordova project へ upstream する必要あり
  • 33. 33 Electron 構造と設計思想 Chromium Node plugin (Native) 設計思想: WebView (Chromium) と node をアプリに組み込んでしまう • WebView は組み込まれた Chromium の物を利用する • Native Layer とのやり取りは node が受け持つ • WebView と node 間のやり取りは Chromium の IPC 機能を利用する Chromium Electron Application node WebView v8 v8 node.js Node plugin (Native) WebApp (Browser part) Chromium IPC Blink WebApp (Renderer part)
  • 35. 35 課題 Electron の課題 • Electron の開発はほぼ1人の肩に掛かっている (zcbenz) • リソースも足りていない状況 • Chromium/node を抱え込んでいる • 配布ファイルサイズが大きくなってしまう (~20MB位) • Chromium 以外のブラウザを利用したい場合の対応は難しい • 最新の Chromium/node Update 反映にタイムラグがある Cordova/Electron 両対応 Hybrid App を開発する際の課題 • Cordova / Electron では、WebAppの構成が異なる • アプリコードの使い回しをする際にはハードルになりそう
  • 37. 37 Cordova vs Electron 比較 開発者 Apache Foundation GitHub.com (@zcbenz) ターゲットアプリ (原則) モバイルアプリ デスクトップアプリ PF Android, iOS, Ubuntu, Windows desktop, browser Amazon Fire OS, Blackberry, FireFox OS, Mac OS X, Web OS, Windows phone 8 Windows, Mac OS X, Linux WebView (原則) OS付随のブラウザを使用 内包する Chromium を使用 WebApp構成 ソリッド スレッドが明示的に Browser(main)/Renderer(UI) で分かれてい る plugin cordova plugin (Cordova が提供する API) node module (node が提供) plugin repository npm (ecosystem:cordova) n/a
  • 39. 39 終わりに 現況で Hybrid アプリケーションを実現する場合に使える、2つの代表的な FWs の構造を確認してみた。 それぞれの構成を大まかに理解できたのであれば嬉しい。 ご清聴ありがとうございました

Editor's Notes

  1. Hybrid App を実現するための OSS フレームワークはいくつか存在します。 今回はその中で Apache Cordova と Electron について、その内部構造がどうなっているかを深掘りしていきたいと思います。 Cordova の内部構造は対象OS毎に大きく異なります。ここではAndroid/iOS/Ubuntu向けのCordova実装がどうなっているかを紐解き、仮に別のOS上に Cordova を移植したい場合にはどのような作業を行うべきなのかを明らかにしていきます。 また、Electron は Cordova とは異なるアプローチで Hybrid App の実現をしています。これらを対比することで、Hybrid App を実現する仕組みについてより深く理解できればと思っています。
  2. WebApp - [Cordova JS lib] - (WebView) - [Cordova Native lib] - Native implmentation
  3. src/io/cordova/hellocordova/MainActivity.java CordovaActivity.java: 106 onCreate() CordovaActivity.java:134 makeWebView() CordovaWebViewImpl.java createEngine() にて SystemWebViewEngine を登録 CordovaBridge CordovaActivity.java:140 init() -> appView.init() は SystemWebViewEngine#init() を指す SystemWebViewEngine.java:89 init() SystemWebViewEngine.java:119 bridge = new CordovaBridge() addJavaScriptInterface SystemWebViewEngine.java:89 init() SystemWebViewEngine.java:250 exposeJsInterface() loadUrl MainActivity.java:32 index.html cordova.js の読み込み・初期化
  4. CordovaBridge # assets/www/cordova-js-src/exec.js - addJavaScriptInterface() JS側: _cordovaNative の retrieveJsMessages(bridgeSecret, true) をコール Native側: SystemWebViewEngine#exposeJsInterface() → webView.addJavaScriptInterface() ☆ これだけだとダメな理由は? :deplicated になるから? :動作不安定? - prompt() JS側: prompt() で 値 と 'gap:', 'gap_bridge_mode:', 'gap_poll:', 'gap_init:' で始まる文字列を渡す Native側: SystemWebChromeClient#onJsPrompt() が発火 (ChromeのAPI [SystemWebChromeClient extends WebChromeClient]) URL の protocol の値に応じて動作を振り分け 現在は基本 addJavaScriptInterface() [JS_OBJECT mode] で行う。 幾つかのバグのようなケースでのみ PROMPT モードに fallback する設計。
  5. ☆ Network Online/Offline で JS 層にイベントがあることを通知している CordovaWebViewImpl#sendPluginResult(PluginResult cr, String callbackId) -> NativeToJSMessageQueue#addPluginResult(PluginResult result, String callbackId) -> NativeToJSMessageQueue#enqueueMessage(JsMessage message) queue.add(message) BridgeMode#onNativeToJsMessageAvailable(final NativeToJSMessageQueue queue) で message をハンドル -> 実装は3種類 - NoOpBridgeMode JS側: pollOnce() を定期的(50ms毎)に実行 → JS->Native のコール法に基づいて Native の queue を取得 - LoadUrlBridgeMode CordovaWebViewImpl#init() で addBridgeMode() Native側: [API] LoadUrlBridgeMode#onNativeToJsMessageAvailable() → NativeToJsMessageQueue#popAndEncodeAsJs() → JsMessage#encodeAsJsMessage() で JS側の callbackFromNative() を呼ぶコードを生成 これを webView.loadUrl("javascript:"+[コード], false); でコール # 念のため最後に pollOnce() を実行している。queue の確実な flush が目的? - OnlineEventsBridgeMode SystemWebViewEngine#init() で addBridgeMode() JS側: hookOnlineApis() にて 'online', 'offline' のイベントを addEventListener() でひっかける → pollOnce() から _cordovaNative の retrieveJsMessages(bridgeSecret, true) をコール どれを選ぶかは、JS側の _cordovaNative.setNativeToJsBridgeMode(int bridgeSecret, int value) による android の cordova.js ではアプリで指定しない限り OnlineEventsBridgeMode を採用する
  6. UIWebView (iOSのWebViewそのまま) # Cordova iOS 4.0.0 以降では WKWebView が利用可能に self.viewController = [[MainViewController alloc] init]; (AppDelegate.m:35) -> MainViewController : CDVViewController (MainViewController.h:32) -> CDVViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate> (CordovaLib/Classes/Public/CDVViewController.h:30) ○ WebApp のロード法 config.xml の <content src="[file]" /> を参照してロードする -> loadSettings でロード (CordovaLib/Classes/CDVViewController.m:169) -> [self.webView loadRequest:appReq]; (CordovaLib/Classes/CDVViewController.m:474)
  7. # WKWebKit の参考 # http://www.joshuakehn.com/2014/10/29/using-javascript-with-wkwebview-in-ios-8.html XHR: XMLHttpRequest() をローカルに対して行う iFrame: 登録している hash の値を変化させ、それを native 側で検知する 7通り IFRAME_NAV : デフォルト XHR_NO_PAYLOAD XHR_WITH_PAYLOAD XHR_OPTIONAL_PAYLOAD IFRAME_HASH_NO_PAYLOAD IFRAME_HASH_WITH_PAYLOAD WK_WEBVIEW_BINDING : iOS8,9 以後の WKWebKit ではこれを用いる # default: IFRAME_NAV, WKWebKit で動作している場合は WK_WEBVIEW_BINDING # それ以外は cordova.exec.setJsToNativeBridgeMode で明示的に設定 ○ WK_WEBVIEW_BINDING の場合: window.webkit.messageHandler (.cordova.postMessage(command)) (cordova-js-src/exec.js:180) ○ それ以外の場合: ○ Native 側から stringByEvaluatingJavaScriptFromString を用いない場合 - XHR_NO/WITH/OPTIONAL_PAYLOAD の場合 pokeNativeViaXhr() CDVViewController viewDidLoad -> [CDVURLProtocol registerViewController:self]; (CDVViewController.m:282) CDVURLProtocol を登録 XTMLHTTPRequest() で /!gap_exec? で始まるURLを発布 CDVURLProtocol canInitWithRequest/startLoading がトリガされる -> canInitWithRequest の方でコマンドを queue に入れる -> XHR_WITH/OPTIONAL_PAYLOAD の場合は enqueueCommandBatch -> XHR_NO_PAYLOAD の場合は processXhrExecBridgePoke -> stringByEvaluatingJavaScriptFromString で JS の nativeFetchMessages() を実行 -> 結果を enqueueCommandBatch CDVCommandQueue executePending で queue に登録された command を実行 # XHR_NO_PAYLOAD の場合は改めて Native 側から JS 側に command の取得に行く。。。 - IFRAME_HASH_NO/WITH_PAYLOAD の場合 pokeNativeViaIframe() iframe の DOM を display='none' で DOM tree に追加して、表示するコンテンツを file///#%01, %02 と通知することで Native 側に JSMessage が追加されたことを通知 -> shouldStartLoadWithRequest で fetchCommandsFromJs/executePending で実行 - IFRAME_NAV pokeNativeViaIframe() gap://ready を追記した iframe を DOM tree に追加することで Native 側に JSMessage が追加されたことを通知 -> shouldStartLoadWithRequest で fetchCommandsFromJs/executePending で実行 ○ [webView stringByEvaluatingJavaScriptFromString] を用いて Native側からデータ取得 nativeEvalAndFetch (exec.js:312) <- Native 側からコールする # XHR_NO_PAYLOAD の場合と、Native->JS のコールをする場合への回避コード。。。
  8. ● WebView をどのように実現しているか QQmlApplicationEngine で用意されている WebView provided by com.canonical.Oxide (based on chromium) Window 中に CordovaView を貼り付け plugin\ を pluginとして読み込み onLoadChanged() -> Cordova::loadFinished() -> Cordova#initPlugins() -> pluginWantsToBeAdded -> onPluginWantsToBeAdded -> CordovaWrapper(as cordova_wrapper.js).addPlugin ● plugin の実装法 - CPlugin を継承する - API 関数定義を signals: 以下に定義する -> signals: 以下に定義することで cordova_wrapper.js 中からのコールが可能になる。 - 戻り値は callback もしくは callbackWithoutRemove を呼び出すことで行う - ** CAUTION ** callback() に渡す callbackID を切り替えることで、win/fail の通知 を使い分ける。 scID -> win, ecID -> fail ● JS -> Native のコールの仕方 com.canonical.Oxide のメッセージングの仕組みを使う cordova.exec() から window.oxide.sendMessage("from-cordova", message) でメッセージを send → CordovaViewInternal の ScriptMessageHandler が受け取る → CordovaWrapper(as cordova_wrapper.js).messageHandler を実行 -> execMethod() により、登録していた plugin の function がコールされる ● Native -> JS のコールの仕方 cordova.exec() 中に cordova.callbacks[id] に対してコールバックを記録しておく Plugin の実行終了時に callback もしくは callbackWithoutRemove をコールする ** CAUTION ** 戻り値の 文字列化後のサイズが 1000 を超えると truncate される(!!) 'cordova.callback()' か 'cordova.callbackWithoutRemove()' のコードを生成 jsExec() -> emit javaScriptExecNeeded() -> onJavaScriptExecNeeded -> webView.rootFrame.sendMessage(); によって MessageHandler 起動 * window.oxide.addMessageHandler に登録されている function により eval(args.code); -> cordova.callback() or cordova.callbackWithoutRemove が実行される -> 登録していた callback を kick.
  9. WebApp - [Cordova JS lib] - (WebView) - [Cordova Native lib] - Native implmentation