问题描述
我在浏览Android WebView文档时遇到 ServiceWorkerController 并决定尝试一下.不幸的是我一直无法截获任何电话.我知道 WebViewClient.shouldInterceptRequest ,但有兴趣了解有关ServiceWorkerController的更多信息.不幸的是,这些文档比我已经在下面实现的稀疏.任何帮助,将不胜感激.
I came across ServiceWorkerController while looking through the Android WebView documentation and decided to give it a try. Unfortunately I have been unable to get intercept any calls. I am aware of WebViewClient.shouldInterceptRequest but am interested in learning more about the ServiceWorkerController. Unfortunately the documents are a little sparse beyond what I have already implemented below. Any help would be appreciated.
我整理了一个由单个Activity组成的简单应用.
I have put together a simple app consisting of a single Activity.
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.ServiceWorkerClient;
import android.webkit.ServiceWorkerController;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
private final static String LOGTAG = MainActivity.class.getSimpleName();
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ServiceWorkerController.getInstance().setServiceWorkerClient(new ServiceWorkerClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
Log.e(LOGTAG, "in service worker");
return null;
}
});
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient());
Log.e(LOGTAG, "about to load URL");
mWebView.loadUrl("https://www.google.com");
}
@Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
}
还有我相关的build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
推荐答案
我发现这个问题是个误会.我相信安装ServiceWorkerClient
可以使我拦截来自应用程序中所有WebView的所有请求,而不管其域如何.事实并非如此. ServiceWorkerClient
仅在Web视图已安装ServiceWorker的情况下称为.然后,来自所有服务工作人员的所有服务工作人员请求都将被传送到ServiceWorkerClient
.这意味着如果您希望在应用程序的所有Web视图中拦截所有网络请求,则还需要在WebViewClient
上覆盖shouldInterceptRequest()
.
I have found the issue to be a misunderstanding. I had believed that installing a ServiceWorkerClient
would allow for me to intercept all requests from all WebViews in my app regardless of domain. This appears to not be the case. The ServiceWorkerClient
is only called if a webview has installed a ServiceWorker already. All service worker requests from all service workers are then funneled to the ServiceWorkerClient
. What this means is that if you wish to intercept all network requests within all webviews in your app you will also need to override shouldInterceptRequest()
on your WebViewClient
as well.
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.ServiceWorkerClient;
import android.webkit.ServiceWorkerController;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.Nullable;
public class MainActivity extends Activity {
private final static String LOGTAG = MainActivity.class.getSimpleName();
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ServiceWorkerController swController = ServiceWorkerController.getInstance();
swController.setServiceWorkerClient(new ServiceWorkerClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
Log.e(LOGTAG, "in service worker. isMainFrame:"+request.isForMainFrame() +": " + request.getUrl());
return null;
}
});
swController.getServiceWorkerWebSettings().setAllowContentAccess(true);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
WebView.setWebContentsDebuggingEnabled(true);
webSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient() {
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,
WebResourceRequest request) {
Log.e(LOGTAG, "in webview client. isMainFrame:"+request.isForMainFrame() +": " + request.getUrl());
return super.shouldInterceptRequest(view, request);
}
});
Log.e(LOGTAG, "about to load URL");
//service worker handler only invoked on pages with service workers
mWebView.loadUrl("https://developers.google.com/web/fundamentals/primers/service-workers/");
}
@Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
}
这篇关于如何在Android上使用ServiceWorkerController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!