• トップ
  • ブログ一覧
  • 【Android】WebViewのTips
  • 【Android】WebViewのTips

    笹川(エンジニア)笹川(エンジニア)
    2024.10.18

    IT技術

    WebViewのTipsをあれこれ紹介

    (株)ライトコードでモバイルアプリケーションをメインで色々開発している笹川(ささがわ)です!

    今回はWebViewを使う場合のTipsをいくつか紹介したいと思います

    なんでWebView使うの?

    ネイティブでモバイルアプリケーションを開発してるエンジニアの多くはWebViewについてはあまり良い印象を持っておらず、

    使わなくて良いならなるべく使わないように仕様や設計の調整をしている方が多いと思います。

    その中でなぜ使うのかというと、様々なプラットフォームでなるべくUIを統一したいときに使うことが多いのではないしょうか。

    利用規約などをWebViewで表示しているのを見受けられますが、あれも同じ考えの認識です。

    どのプラットフォームでの統一された表示をしたい!

    なら、そもそもクロスプラットフォームのフレームワークを使えばいいじゃんという意見ももちろん賛成で、私としてもそちらを推奨します。

    そこまで分かっていてWebView使わなきゃなの?

    一例ですが、Android,iOSとネイティブで、同じような機能がWebページとして別々で開発が続けられてきて、一部のUIだけ統一をしたいといった要件は出てくることがあります。

    そのときが出番になります。

    最終的には全て統一して足掛かりとして一部..という場合はクロスプラットフォームのフレームワークを導入で良いと思います。

    本題のTips

    Chrome Dev Toolsを使う

    これはWebViewを利用した画面開発ではほぼ使う機能かと思います。

    WebViewを利用している画面クラスで下記を追加します。

    1WebView.setWebContentsDebuggingEnabled(true)

    その後にアプリを起動してadb接続しているPCのChromeから下記にアクセスします。

    1chrome://inspect/#devices

    接続と起動がうまく行っていれば端末名がリストに表示されるので、そこからinspectしてデバッグできます。

    スタイルが当たっているか、スクリプトがエラーになっていないかなどを確認しやすくなります。

    もちろんネイティブ側の実装でエラーやコンソールを確認することはできますが、DevToolsを使った方が楽な場合が多いのでおすすめです。

    faviconが見つからず404エラーがでる

    Stacktraceなんかでもたまに見る事象です。

    こちらはWebViewClientCompatを使って解消できます

    1
    2override fun shouldInterceptRequest(
    3    view: WebView,
    4    request: WebResourceRequest
    5): WebResourceResponse? {
    6    val url = request.url.toString()
    7    // faviconのリクエストをフィルタリングして無視
    8    url.takeIf { it.contains(FAVICON) && request.isForMainFrame.not() }?.let {
    9        return WebResourceResponse(MINE_TYPE_PNG, null, null)
    10    }
    11    /// 割愛
    12}

    リクエストの制御自体ができない場合があるので、来ちゃったら適当に返してあげれば抑制はできます。

    JavaScriptなどのフロントエンド向けのライブラリを利用したい

    WebViewで表示するコンテンツの多くはモバイルアプリケーション開発メンバーではなく、フロントエンドの方々実装することが多いと思います。

    そうなるとInterFaceの都合上、QSなどのフロントエンドのデファクトなライブラリを使うことがあります。

    2023年にJetpackでもJSエンジンのライブラリが公開されましたが、まだ不安定な部分もあるので、

    Ziplineというライブラリを使うと良さそうです。

    1implementation("app.cash.zipline:zipline:1.14.0")

    こんな感じでJSのスクリプトの平文を渡してあげれば結果を返却してくれます。

    1
    2    /* JSのスクリプト実行 */
    3    @OptIn(EngineApi::class)
    4    private fun evaluateJavaScript(script: String): String {
    5        val zipline = Zipline.create(Dispatchers.Default)
    6        val result = zipline.quickJs.evaluate(script) as String
    7        zipline.close()
    8
    9        return result
    10    }

    先ほど例に挙げたQSを利用する場合、QSを1つのスクリプトファイルに変換し、下記のように呼び出せば利用可能です。

    1
    2    @SuppressLint("RestrictedApi")
    3    fun executeJavaScript(target:String): String {
    4        // JavaScriptコードを定義
    5        val script = """
    6        var Module = globalThis.Module;
    7        var result = Module.Bridge.stringify('$targer');
    8        result;
    9    """.trimIndent()
    10        // JavaScriptファイルとスクリプトを連結して評価
    11        val combinedScript = "$qs\n;$script"
    12        val result = evaluateJavaScript(combinedScript)
    13        return result
    14    }

    おわりに

    3つほどTipsを紹介させていただきました。

    今回紹介できなかったもの、WebViewだけじゃないTipsなどはまた別の機会に紹介予定です。

    WebViewの利用は開発だけでなく運用も難しいですが、少しでも快適に安全に利用できると良いなと思っています。

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    笹川(エンジニア)
    笹川(エンジニア)
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background