好消息,从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参考文档:
public WebResourceResponse shouldInterceptRequest (WebView view, String url)
自 API level 11 开始提供。
通知宿主应用程序资源请求,并允许应用程序返回数据。如果返回值为空,
WebView
将按原样继续加载资源。否则将使用返回的响应和数据。注意:此方法由网络线程调用,因此客户端在访问私有数据时应谨慎。参数
view
请求资源的WebView
。
url
资源的原始 URL。返回值
包含响应信息的
WebResourceResponse
对象或 null,如果WebView
应该自行加载资源。
还请查看WebResourceResponse。
希望这可以帮助您。
ajaxStart
和ajaxComplete
按以下方式进行:// 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();
}
}
以下是如何在Activity
中使用AjaxHandler
:
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
"});");
});
}
}
主要思想来自这里,稍作修改后呈现出来。
虽然提交答案有点晚了,但希望这也能帮助其他人!
最终我还是使用了问题中描述的方法;
我拦截了一些特定的请求,例如:foo://bar/get/1?callback=foobar
,然后解析了URL
并调用了一个带有实际数据的JavaScript回调函数。
回调函数在URL
的查询部分中定义,因此在上面的示例中,它将是:foobar();
调用该函数很容易,只需使用:yourWebView.loadUrl("javascript:foobar('somedata')");
现在是2023年,我遇到了同样的问题。
我使用了shouldInterceptRequest()
方法来解决它。这个技巧是通过过滤被拦截的请求并根据情况采取行动。
shouldInterceptRequest()
方法拦截所有在你的WebView
上发出的请求。在我的情况下,我知道正在进行的确切请求以及与请求相关联的确切URL。
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String sURLPatternExpected = "";
if (request.getUrl().toString().contains(sURLExpected)) {
String sExactURLExpected = "";
if (!request.getUrl().toString().equals(sExactURLExpected)) {
// User is going outside your expected URL.
} else {
// User is going outside your expected URL.
}
}
return null;
}
http://example.com/app/resource?message=hello
这样的URL感兴趣,则通过以上方式进行过滤,将防止你对像http://example.com/favicon.ico
这样的URL采取行动。null
以让WebView
正常处理请求。