AndroidのWebViewでバックグラウンドでの遅延実行を考える。

WebViewで読み込み後数秒DelayさせてからScriptをInjectionさせたいことってありますよね。動的に生成されるページなどである程度Delay挟んでからDOM取得したいとかそんな感じです*1。そんなとき手癖で以下のようなコードをまずは書いてみました。

private val script = """
    setTimeout(() => {
        // ここにやりたいことを書く
    }, 5000);
""".trimIndent()

// 中略

webView.webViewClient = object: WebViewClient() {
    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        view?.loadUrl("javascript:$script")
    }
}

フォアグラウンド動作時はこれでもいいのですが、バックグラウンドでは意図した動作になっていないことがlogcatの出力などから確認できました。ググったらJavaScript制御でのTimeout系動作がバックグラウンドに行ったら動作しないっぽい*2ようなのでWebViewの外で遅延制御するようにしてみます。

private val script = """
    // ここにやりたいことを直接書く
""".trimIndent()

// 中略

webView.webViewClient = object: WebViewClient() {
    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        Handler(Looper.getMainLooper()).postDelayed({
            view?.loadUrl("javascript:$script")
        }, 5000)
    }
}

簡単な動作確認ではこれで動いているっぽいです。
ただ、確かTimer設定しない処理ってあまり時間は厳密に動いていなかったような気がするので、厳密にやるにはTimerでやるかフォアグラウンドでのJavaScript動作に任せるとかになるんですかね。

*1:正直あまり賢くはない方法だと思います。が、適当に作る、あるいは外部サイトに対して何かしたいときはこんなんでもいいのかなと。

*2:参考にしました: Android WebView 内の JavaScript で RxJS の bufferTime/timeout等 を使うと端末スリープ後5分経過で subscribe が来なくなる件