ネイティブアプリなんだけどネイティブのコードは極力書かず、WebViewを使ってhtml+JavaScriptを使ってアプリを組みたい。今回はAndroid, Javaで作ってみる。
- ‘16/12/01: 環境をAndroidStudio、使用言語をKotlinに変更しました
WebViewを全画面の大きさで配置する
レイアウトのxmlで指定する
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
layout_width、layout_heightともにmatch_parentを指定することで全画面にする
htmlの表示
配置したWebViewを使ってJavaからブラウザを操作する。
// MainActivity.kt |
findViewByIdでWebViewを取得して、WebView#loadUrlでページの読み込みを指定できる- インターネットからウェブページを読み込むためにはAndroidManifest.xmlで
<uses-permission android:name="android.permission.INTERNET"/>を指定して、アプリでのインターネット利用を有効にする必要がある
アセット内のhtmlの表示
外部のurlではなく、アセットに含めたhtmlファイルを読み込むにはURLにfile:///android_asset/〜と指定する
// Kotlin |
- Android Stuidoでassetsフォルダを追加するには、appを選択して、メニューのFile > New > Folder > Assets Folder
アセット内のhtmlから画像、JavaScript、CSSを読み込む
html内で相対パスで書けばアセット内のファイルが自動的に読み込まれる
<link rel="stylesheet" type="text/css" href="main.css" /> |
JavaScriptとネイティブの連携
JavaScriptからネイティブ(Java)を呼び出す
JavaScriptからネイティブに対してなにか起動するにはWebViewにインタフェース用のクラスを定義し
class MyJavaScriptInterface(private val context: Context) { |
オブジェクトを登録してやると
// Kotlin |
JavaScriptから呼び出すことができる:
// JavaScript |
WebView#addJavascriptInterfaceでインタフェースの登録- 登録したインタフェースのpublicメソッドをJavaScriptから呼び出せる
- 型を自動的に変換してくれる、便利
- セキュリティ的に、Jelly Bean以降はJavascriptInterfaceアノテーションがついたpublicメソッドだけが呼び出せる。(リファレンスを参照すること)
- それだとセキュリティ的に危険なので、WebChromeClient#onJsAlertを使う方法がよいらしい(Android の WebView で addJavascriptInterface を使わず情報を渡す - Qiita)
ネイティブからJavaScriptを呼び出す
WebView#loadUrlを使用する:
// Kotlin |
WebView#evaluateJavascriptを使う- 第二引数は結果受け取りコールバック
- API level 19(KITKAT)より前の場合には上のメソッドがないので、JavaScriptのコードを表す文字列の前に
"javascript:"を追加した内容をurlとしてloadUrlを呼び出すことでJavaScriptコードが実行される
URLリクエストを横取りする
Javaで登録したインタフェースのメソッドをJavaScriptから呼び出せるので、使うかどうかわからないけど、URLリクエストも横取りできる。
// Kotlin |
- WebViewに対して
setWebViewClientでWebViewClientを登録できて、そのshouldOverrideUrlLoadingでURLに対する処理を扱える- 横取りしてなにか処理した時には
trueを返す、そうでなくて通常の読み込みを継続する場合にはfalseを返す
- 横取りしてなにか処理した時には
実行例
