问题描述
基本上 JavascriptInterface
接收来自 WebView
的 Click 事件,然后我需要多次更改 HTML 元素,问题是 WebView 只显示最后一次更改,这意味着渲染不是立即的.
问题:如何使webview.loadUrl("javascript:updateProgress(20);");
生效并立即更改WebView内容?
- - - - - - - - - - - - - - - -
老问题:
我的 WebView 中有一个 HTML 进度条,我可以简单地通过从 webview.loadUrl("javascript:updateProgress(20);");
运行 onCreate()
来更新进度条值。
// JavaScript in WebView
function updateProgress(percentage){
document.getElementById('progressBar').style.width = percentage + '%';
}
现在,我有一个类可以将二进制数据发送到连接的 BLE 设备,我以 Google BluetoothLeGatt 中的示例为例,并在 BluetoothLeService.java 中添加了一个写入特性(发送数据)的方法.
public void WriteCharacteristic(BluetoothGattCharacteristic characteristic,byte[] data,MainActivity mainactivity){
byte[] data_twenty_byte = new byte [20];
int progress_count = 0;
while(get_next_twenty_byte(data,data_twenty_byte)){
characteristic.setValue(data_twenty_byte);
mBluetoothGatt.writeCharacteristic(characteristic);
progress_count++;
mainactivity.webview.loadUrl("javascript:updateProgress(" + progress_count + ");");
}
}
问题是在 WriteCharacteristic()
运行时 WebView 不会更新(重绘/重新渲染),WebView 仅在 WriteCharacteristic()
之后重绘/重新渲染完成,表示进度条 100%。
注意:我已经尝试过 runOnUiThread(new Runnable() {});
我的问题是,如何强制 mainactivity.webview
立即重绘/重新渲染?
谢谢,
解决方法
如我的评论中所述,将长时间运行的进程推送到后台线程,然后在 ui 线程上运行 webview 更新应该可以实现您想要实现的目标。这是我拼凑的一个简单示例:
package com.example.myapplication
import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebView
import kotlin.concurrent.thread
class MainActivity : AppCompatActivity() {
lateinit var webView: WebView
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
webView = WebView(this)
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(this,"app")
setContentView(webView)
val html =
"""
<html>
<head>
<script type='text/javascript'>
function updateProgress(progress) {
let el = document.getElementById('progress');
el.innerText = progress;
}
</script>
</head>
<body>
<p>Value: <span id='progress'>0</span></p>
<button onclick='app.startUpdates();'>Start Update</button>
</body>
</html>
""".trimIndent()
webView.loadData(html,"text/html","UTF-8")
}
@JavascriptInterface
fun startUpdates() {
doSomething()
}
private fun doSomething() {
thread {
for (i in 1..100) {
runOnUiThread { webView.evaluateJavascript("updateProgress($i);",null) }
Thread.sleep(10)
}
}
}
}