2010-10-15 128 views
14

我想要一个HTML/javascript应用程序,在WebView中运行,使AJAX调用由Java代码处理。
理想的情况是只需拦截呼叫(简单,只需使用shouldOverrideUrlLoading())并“返回”一些数据。
但是,除了使用loadUrl()调用javascript函数,我没有找到一种方法来“返回”对WebView的响应。
这对我不起作用,因为HTML/javascript应用程序是我无法控制的应用程序。就HTML/javascript应用程序而言,它只是调用一个AJAX并接收一些数据。Android:拦截来自WebView的AJAX呼叫

对此有何看法?

+0

发送表单数据后可以得到ajax响应吗?在webview中从远程url形成网页显示 – 2016-04-16 07:20:53

回答

2

最后,我用了问题中描述的方法;

我拦截了一些特定的请求,如:foo://bar/get/1?callback=foobar然后解析URL并调用一个JavaScript回调函数与实际数据。
回调函数是在URL的查询部分定义的,所以在上面的例子中,这将是:foobar();

调用该函数很简单,只需使用:yourWebView.loadUrl("javascript:foobar('somedata')");

+0

Erik可以请你详细说明一下,你如何为AJAX请求处理重载URL,并告诉我如何处理来自Java的AJAX请求..我也知道拦截机制... im困在同样的问题...需要帮助..谢谢 – jyotin 2011-03-30 06:48:37

31

好消息大家:随着API级别11,他们将shouldInterceptRequest方法放入WebViewClient类中。它还触发WebView触发器内的应用程序请求。可以按如下方式重写它:

@Override 
public WebResourceResponse shouldInterceptRequest(WebView view, String url) 
{ 
    if (magicallyMatch(url)) 
     return new WebResourceResponse("application/json", "utf-8", magicallyGetSomeInputStream()); 

    return null; 
} 

Android Reference

公共WebResourceResponse shouldInterceptRequest(的WebView视图,字符串URL)

自:API级别11

通知资源请求的主机 应用和允许该资源请求的 应用程序返回 数据。如果返回值为空,那么 WebView将照常继续加载 资源。否则,将使用 返回响应和数据。 注意:此方法由 网络线程调用,因此在访问 私有数据时,客户端应该谨慎使用 。

参数

view请求该资源的WebView

url资源的原始网址。

返回

将含有 响应信息或空如果 WebView应该加载资源 本身WebResourceResponse

另请检查WebResourceResponse

希望这会有所帮助。

+0

这应该被标记为正确的答案。 – 2013-07-19 19:17:09

+1

没有办法让它在没有3.x的手机上工作?发送表单数据后, – NoBugs 2013-09-11 06:20:49

+1

可以得到ajax响应吗?从远程URL在webview中形成网页显示 – 2016-04-16 07:21:01

10

可以使用JavascriptInterface拦截AJAX与jQuery方法ajaxStartajaxComplete以下方式调用一起:

// our JavascriptInterface 
public class AjaxHandler { 

    private static final String TAG = "AjaxHandler"; 
    private final Context context; 

    public AjaxHandler(Context context) { 
     this.context = context; 
    } 

    public void ajaxBegin() { 
     Log.w(TAG, "AJAX Begin"); 
     Toast.makeText(context, "AJAX Begin", Toast.LENGTH_SHORT).show(); 
    } 

    public void ajaxDone() { 
     Log.w(TAG, "AJAX Done"); 
     Toast.makeText(context, "AJAX Done", Toast.LENGTH_SHORT).show(); 
    } 
} 

,这里是如何AjaxHandlerActivity使用:

public class MainActivity extends Activity { 

    private static final String TAG = "MainActivity"; 

    private WebView webView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     // get web view 
     webView = (WebView) findViewById(R.id.web); 

     // configure web view 
     final WebSettings webSettings = webView.getSettings(); 
     webSettings.setBuiltInZoomControls(true); 
     webSettings.setJavaScriptEnabled(true); 

     webView.loadUrl("http://foo.com"); 

     // add javascript interface 
     webView.addJavascriptInterface(new AjaxHandler(this), "ajaxHandler"); 

     // override onPageFinished method of WebViewClient to handle AJAX calls 
     webView.setWebViewClient(new WebViewClient() { 

       @Override 
       public void onPageFinished(WebView view, String url) { 
        super.onPageFinished(view, url); 

        view.loadUrl("javascript:$(document).ajaxStart(function (event, request, settings) { " + 
          "ajaxHandler.ajaxBegin(); " + // Event called when an AJAX call begins 
          "});"); 
        view.loadUrl("javascript:$(document).ajaxComplete(function (event, request, settings) { " + 
          "ajaxHandler.ajaxDone(); " + // Event called when an AJAX call ends 
          "});"); 

      }); 
    } 
} 

主要思想取自here并进行了一些调整。
尽管提交答案有点迟,但希望这对其他人也有帮助!

+0

这是一个很好的解决方案。但我怎样才能从js代码中获取AjaxHandler中的请求参数? – 2015-07-06 10:13:48

+1

伟大的解决方案,谢谢。另外,我只是想让知道在这种情况下ajaxStop可能会更好,因为当ajax实际上停止加载时会触发。 来源:http://stackoverflow.com/a/4421115/706833 – iGoDa 2015-08-03 17:09:22

+0

@ S1LENT WARRIOR我把代码照原样,但任何如何吐司不显示 – 2016-04-16 04:20:23