【问题标题】:Handling Callbacks with Webview Android使用 Webview Android 处理回调
【发布时间】:2021-04-24 18:55:58
【问题描述】:

您好,我正在创建一个 Android 应用程序。我不喜欢使用 Android 的 UI 系统,并选择使用 WebView 进行 UI 设计,因为它对我来说更容易来自 HTML5 背景。 我已经尝试过像 Cordova 和 Phonegap 这样的平台,但它们并没有像我一样给我确切的控件 ID,因为我也有 Java 背景。所以重申一下,我仅将 WebView 用于 UI。

话虽如此,我想在 Web 视图上运行少量 JavaScript 代码,即网络调用。我有一个使用 OkHttp 的网络后端,并且可以使这些连接正常!但我无法以对我目前对 webview 的了解友好的方式取回任何数据。

这是我的 JavaScript 函数签名:

function makeRequest(method,url,data,callback){
    ... Code Here ...
}

我想这样称呼它:

makeRequest("GET","http://www.example.com/",{
    "key1" : "value1",
    "key2" : "value2"
},(code,responseJSON) => {
    ... Handle Response...
});

到目前为止,在我的 Android/Java 方面,我有这个:

@JavascriptInterface
public void makeRequest(String method, String url, String data, ??? callback){
    ... Handle Request Java-side ...
}

当请求被处理时,我想以某种方式调用回调函数。 像 EventListener 之类的,但我对类型“???”感到困惑应该, 或者我将如何调用该函数以便 JavaScript 代码可以接收 它的回调并继续。

我已经有了通过我的 JavaScriptInterface 和 webview 工作的单向代码。 而 JSON 是没有问题的,因为它在 JS 代码中转换为字符串,而 GSON 可以 解析并得到我需要的东西。就是这个回调让我难住了!

提前感谢您的帮助:)

【问题讨论】:

    标签: javascript java android webview


    【解决方案1】:

    好的,看起来预期的行为是不可能的,但是使用 API 21+,您可以访问 Webview#postMessage() 方法在运行时之间来回交谈。 这基本上就是我所做的:

    JavaScript 代码

    function makeHTTPRequest(method,url,data,callback){
        // may have to do a check on data
        var number = Math.floor(Math.random() * 1000);
        window.host.makeHTTPRequest(number,method,url,JSON.stringify(data));
        window.addEventListener("message",(ev) => {
            var JSONData = JSON.parse(ev.data);
            if(JSONData.id == number){
                callback(JSONData.code,JSONData.payload.data);
            }
        });
    }
    

    Java 代码

    @JavascriptInterface
    public void makeHTTPRequest(int id, String method, String url, String data){
        createRequest(id, method, url, data, new MethodCallBackInterface() {
            @Override
            public void done(String message) {
                parent.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        view.postWebMessage(new WebMessage(message), Uri.parse("*"));
                    }
                });
            }
        });
    }
    

    ID 很重要!调用该方法时,我们必须生成一个 ID,该 ID 发送到主 Java 应用程序并包含在最终的 JSON 代码中,然后发送回 JS 代码。可以检查,如果相等,那么我们可以调用我们的回调。在 Java 端使用线程,确保我想要的异步特性,同时在 JS 端保持回调。

    此方法的工作方式与 HTML 中的 IFrame 之间的通信方式相同。因此,如果我们将 Android 应用程序和外部 Web 应用程序视为沙盒 IFrame,我们可以以相同的方式进行通信。

    【讨论】:

      【解决方案2】:

      你可以这样做,

      public class MyJavaScriptInterface {
          private final MyJavaScriptInterfaceCallBack myJavaScriptInterfaceCallBack;
      
          public interface  MyJavaScriptInterfaceCallBack{
              void clickedAdmission(YourDataType code,String responseJSON);
          }
          public MyJavaScriptInterface(MyJavaScriptInterfaceCallBack myJavaScriptInterfaceCallBack) {
              this.myJavaScriptInterfaceCallBack=myJavaScriptInterfaceCallBack;
          }
      
          @JavascriptInterface
          public void applynow() {
              myJavaScriptInterfaceCallBack.clickedAdmission();
          }
      
      }
      

      然后在你的活动片段中

      您的片段或活动必须在哪里实现 MyJavaScriptInterface.MyJavaScriptInterfaceCallBack接口和方法。

      在 WebView 中设置 javascript 界面

      webView.addJavascriptInterface(new MyJavaScriptInterface(this), "YourRecognizer");
      

      【讨论】:

      • 这仍然是一种方式,就像调用 ``` window.YourRecognizer.applynow() ``` 是您访问此代码的方式。我试图这样调用:WebView JS 代码(带回调)-> Java 代码-> WebView JS 代码回调。我认为最好将其描述为传递一个稍后在异步任务完成时调用的函数,并通过调用作为参数提供的函数(即 CallBack)来通知 WebView/JS 函数该过程已完成。看起来可能不完全支持!
      • This可以帮你
      猜你喜欢
      • 2016-05-10
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多