本文背景:delphi XE10.1
Firemonkey自带的TWebBrower对于JavaScript的交互支持一直不是很好,仅仅提供了一个本地执行JavaScript的方法EvaluateJavaScript,而且该方法不提供JS执行的返回结果。在安卓平台上,EvaluateJavaScript是通过WebView的loadUrl('javascript:' + JavaScript)实现的。
在Android 4.4之后,WebView提供了一个新的执行JS的接口:
procedure evaluateJavascript(script: JString; resultCallback: JValueCallback); cdecl;
该接口可以注册一个获取JS执行结果的回调函数以便在JS异步执行完时返回结果。
TJavaScriptCallBack = procedure(const AResult: string) of object;
TJSResultCallback = class(TJavaLocal, JValueCallback)
private
fCallBack: TJavaScriptCallBack;
public
procedure onReceiveValue(value: JObject); cdecl;
end;
{ TResultCallback }
procedure TJSResultCallback.onReceiveValue(value: JObject);
begin
if Assigned(fCallBack) and (value<>nil) then
fCallBack(JStringToString(value.toString));
end;
这样我们只需创建 一个TJSResultCallBack对象, 并作为WebView.evaluateJavascript接口的第二个参数,就可以异步获取本地执行JS代码的结果。
WebView还提供一个本地代码扩展JavaScript功能的接口:
procedure addJavascriptInterface(object_: JObject; name: JString); cdecl;
该接口注册一个本地实现类,在JS中可以使用指定的名称直接调用该类实现的本地方法。 由于目前不知道怎么直接用Delphi的JNI直接产生一个Java本地对象【注1】,而且Android在高版本中基于安全JS只支持调用本地实现类中标记了“@JavascriptInterface”属性的方法【注2】,所以这里直接使用Java编写了一个代理类:
package tu2.com.jshellper;
import android.webkit.JavascriptInterface;
/**
* Created by tutu on 2017-01-01.
*/
public class JavaScriptHelper {
public interface LocalCallBack {
public String executeCustomJavaScript(String cmd, String param);
}
protected LocalCallBack mLocalCallB