gpt4 book ai didi

javascript - 无法从 Javascript 重新加载 Android WebView

转载 作者:行者123 更新时间:2023-12-02 23:43:36 24 4
gpt4 key购买 nike

我对 Android 开发还很陌生,这种行为很奇怪,或者可能是错误的结果。

项目描述

我正在创建一个带有 WebView 的应用程序,该应用程序加载以前仅在浏览器中使用的 SPA:

  • 我已为 WebView 启用 Javascript
  • 我了解到,要获取一些基本的JS功能(例如alert()),需要设置一个WebChromeClient。

我还添加了一个包含一些 @JavascriptInterface 方法的类来处理网页和 Android 应用之间的通信。

问题

网页在 Javascript 中调用 location.reload(),但这会被 WebView 忽略。

失败的解决方案

我已经有了一个带有 @JavascriptInterface 的类,然后让我们从网页调用 Activity 的一个方法来处理 webview.reload()。< br/>想法很简单,但行不通。

奇怪的是,执行只是停止(在 JS 和 Android 中),没有任何错误,但主线程没有停止,因为应用程序仍然工作并响应事件。

最佳答案

我认为这只是一种解决方法......但有效。

在完成各种方法的执行后,我使用 AsyncTask 来延迟 Activity 中 webview.reload() 的调用。

似乎 Android webview.reload() 触发了某种异常,该异常在某个类中的某个位置进行处理,之后什么也没有发生,只是下一行代码没有执行。可能是与 @JavascriptInterface 有关的东西,或者我只是搬起石头砸自己的脚,但我看不到它。

我需要 Android 领域更专家的建议:还有比这个 AsyncTask 解决方案更优雅的东西吗?

测试项目

下面是一个小型 Android Activity(Kotlin+XML 布局)的代码,它将显示该问题。将它们粘贴到新的 Android Studio 项目中,按一些按钮并检查 Logcat(过滤器“PNK”)。

MainActivity.kt

package it.punkman.webviewreloadbug

import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.webkit.JavascriptInterface
import android.webkit.WebChromeClient
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

class JSInterface(val mainActivity: MainActivity){

private inner class Reloader : AsyncTask<Int, Void, Int>() {
override fun doInBackground(vararg params: Int?): Int {
Thread.sleep(500)
return 0
}

override fun onPostExecute(result: Int?) {
super.onPostExecute(result)
Log.d("PNK","Android - Reload Async Real execute!")
mainActivity.refreshWebView(mainActivity.btnRefresh)
Toast.makeText(mainActivity,"WebView refreshed! OK!",Toast.LENGTH_LONG).show(); //OK
}
}

@JavascriptInterface
fun reloadBug(){
Log.d("PNK","Android - Reload Bug Start")
mainActivity.refreshWebView(mainActivity.btnRefresh)
Log.d("PNK","Android - Reload Bug End")
Toast.makeText(mainActivity,"You cannot see this toast!",Toast.LENGTH_LONG).show(); //Unable to see
}

@JavascriptInterface
fun reloadAsync(){
Log.d("PNK","Android - Reload Async Start")
Reloader().execute(0,null,0)
Log.d("PNK","Android - Reload Async Stop")
}
}

val HTML_SAMPLE_PAGE="""
<!DOCTYPE html>
<html>
<head>
<script>
function refreshPage(){
alert("DOM - Refresh Start");
location.reload(); //Inside an Android WebView this isn't working!
alert("DOM - Refresh End\nNothing refreshed, reload ignored");
}

function refreshPageJSI_Bug(){
alert("JS Interface - Refresh Start");
JSI.reloadBug()
alert("JS Interface - Refresh End NEVER SHOWN!"); //NEVER SHOWN!
}

function refreshPageJSI_Async(){
alert("JS Interface - Refresh Start Async");
JSI.reloadAsync()
alert("JS Interface - Refresh End Async");
}
</script>
</head>
<body>
<script>document.write(new Date())</script>
<br/><br/>
<button style="width:100%" onclick="refreshPage()">HTML - JS Refresh</button><br/><br/>
<button style="width:100%" onclick="refreshPageJSI_Bug()">HTML - JavascriptInterface BUG?</button><br/><br/>
<button style="width:100%" onclick="refreshPageJSI_Async()">HTML - JavascriptInterface with AsyncTask</button>
</body>
</html>
"""

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// For the purpose of this example
// the page is just injected from a string
// but the result is the same

testWebView.settings.javaScriptEnabled=true
testWebView.webChromeClient = WebChromeClient()
testWebView.addJavascriptInterface( JSInterface(this), "JSI")
testWebView.loadData(HTML_SAMPLE_PAGE,"text/html",null)
}

fun refreshWebView(v:View){
Log.d("PNK","Android - Refresh Start")
testWebView.reload()
// OR again using loadUrl - testWebView.loadUrl(HTML_SAMPLE_PAGE)
Log.d("PNK","Android - Refresh End")
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" tools:layout_editor_absoluteY="8dp"
tools:layout_editor_absoluteX="8dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:onClick="refreshWebView"
android:text="Android - Refresh"
android:id="@+id/btnRefresh"/>

</LinearLayout>
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="@+id/testWebView"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>

关于javascript - 无法从 Javascript 重新加载 Android WebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55956017/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com