Android:拦截来自WebView的AJAX调用

时间:2010-10-15 11:54:20

标签: android ajax webview

我想要一个HTML/javascript个应用程序,在WebView内运行以进行由AJAX代码处理的Java次调用。
理想的做法是拦截调用(简单,只需使用shouldOverrideUrlLoading())并“返回”一些数据 但是,除了使用WebView调用javascript函数外,我找不到“返回”loadUrl()响应的方法。
这对我不起作用,因为HTML/javascript应用程序是我无法控制的插入式应用程序。就HTML / javascript应用而言,只需进行AJAX调用并接收一些数据。

对此有何想法?

3 个答案:

答案 0 :(得分:32)

每个人都好消息:使用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

  

public WebResourceResponse shouldInterceptRequest (WebView视图,字符串网址)

     

自:API Level 11

     

通知主持人   应用资源请求和   允许应用程序返回   数据。如果返回值为null,则为   WebView将继续加载   像往常一样资源。否则,   将使用返回响应和数据。   注意:此方法由   网络线程所以客户应该   访问时要小心   私人数据。

     

<强>参数

     

view请求资源的WebView

     

url资源的原始网址。

     

<强>返回

     

包含的WebResourceResponse   响应信息,如果是,则为null   WebView应该加载资源   本身。

同时检查WebResourceResponse

希望这有帮助。

答案 1 :(得分:11)

您可以使用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并提出了一些调整 虽然提交答案有点迟,但希望这对其他人也有帮助!

答案 2 :(得分:2)

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

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

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