前提・実現したいこと
KotlinでAndroidアプリを作成しています。
※アプリ開発に関してはごく基礎的な知識しかなく、勉強しながら進めています。
WebViewを使用して、つながりにくいチケット購入ページへのアクセスを自動リロードにより試みる動作を実装したいです。
具体的には、
0. アクセスしたいページをロード
- ページのHTMLを取得して、「混雑しています」というようなページかどうか判定
- そのページであれば(2秒程度間隔をあけて)リロード、違っていたら(=購入ページにアクセスできていたら)何もしない
という流れです。
発生している問題・エラーメッセージ
なんとか所望の動きはするのですが、20回程度リロードを繰り返していると、ほぼ確実にアプリがフリーズしてしまいます。
自分のサーバー上のテスト用ページでリロードしている限りはフリーズは起こらないので、(混雑のために)サーバーからの応答が遅い場合に問題が発生するのかなと思っています。
また、フリーズしたためにアプリを終了して再度立ち上げると、1度もページをロードできずにフリーズしがちです。
何が原因で、どうやったら安定的な動作を実現できるでしょうか?
(半永久的に自動リロードを繰り返してほしいです)
該当のソースコード
Kotlin
1class MainActivity : AppCompatActivity() { 2 override fun onCreate(savedInstanceState: Bundle?) { 3 super.onCreate(savedInstanceState) 4 val binding = ActivityWebBinding.inflate(layoutInflater) 5 setContentView(binding.root) 6 7 binding.webView.settings.javaScriptEnabled = true // JavaScriptの有効化 8 9 val urlToLoad = "https://this-is-a-reservation-page.com" // アクセスしたいURL(例) 10 var nowHtml = "" // 変数nowHtmlにページのHTMLを代入する 11 val regex = Regex("<h2>This website is busy</h2>") // 混雑時の正規表現(例) 12 13 // JavaScriptコードとAndroidコードの間にインターフェースを作成 14 class WebAppInterface { 15 @JavascriptInterface 16 fun getHtml(html: String) { 17 nowHtml = html 18 } 19 } 20 binding.webView.addJavascriptInterface(WebAppInterface(), "Android") 21 22 binding.webView.webViewClient = object : WebViewClient() { 23 // 読み込み終了時の動作 24 override fun onPageFinished(view: WebView?, url: String?) { 25 super.onPageFinished(view, url) 26 view?.loadUrl("javascript:Android.getHtml(document.documentElement.outerHTML);") 27 // HTMLが取れるのを待つ 28 while (nowHtml == "") { 29 Thread.sleep(100) 30 } 31 if (regex.containsMatchIn(nowHtml)) { // 混雑時 32 nowHtml = "" 33 Thread.sleep(2000) // 2秒間あける 34 view?.reload() 35 } else { // アクセス成功 36 nowHtml = "" 37 } 38 } 39 } 40 binding.webView.loadUrl(urlToLoad) 41 } 42}
試したこと
onPageFinished内でぐるぐる回しているのが良くないのかなと思い、一連の操作をbinding.webView.loadUrl(urlToLoad)のあとに置く、つまり
Kotlin
1binding.webView.loadUrl(urlToLoad) 2binding.webView.loadUrl("javascript:Android.getHtml(document.documentElement.outerHTML);") 3// HTMLが取れるのを待つ 4while (nowHtml == "") { 5 Thread.sleep(100) 6} 7if (regex.containsMatchIn(nowHtml)) { // 混雑時 8 nowHtml = "" 9 Thread.sleep(2000) // 2秒間あける 10 binding.webView.reload() 11} else { // アクセス成功 12 nowHtml = "" 13}
としてみましたが、これだとwhileループが永遠に回ってしまうようです。
HTMLを取得してからif文に入ること・リロードを安定して繰り返すこと、の両立に苦戦しています。
あなたの回答
tips
プレビュー