如何在Android上使用ServiceWorkerController [英] How to use ServiceWorkerController on Android

查看:323
本文介绍了如何在Android上使用ServiceWorkerController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在浏览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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆