强制WebView在特定网络上运行 [英] Force WebView to operate on a certain Network

查看:113
本文介绍了强制WebView在特定网络上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以强制使用 WebView 通过指定的 网络 ?

Is it possible to force a WebView load an URL via a specified Network?

我的设备打开了两个网络连接:wifi和移动数据.移动数据网络被设置为用于传出连接的默认网络(因此,连接管理器将为

My device has two network connections open: wifi and mobile data. The mobile data network is set to be the default network for outgoing connections (so the connectivity manager returns the mobile data network for connectivityManager.getActiveNetwork()).

我要加载的网页(从 http://10.0.0.1:80 )正在通过wifi连接的Web服务器上运行.因此,由于无法通过移动数据访问Web视图,因此无法加载到页面.

The webpage that I'm trying to load (from http://10.0.0.1:80) is running on a web server which is connected over wifi. So the web view fails to load to page because it's unavailable via mobile data.

推荐答案

因此,我自己对此主题进行了更多研究,并发现了一些有用的信息:

So I dug a little bit more in this topic by myself and found some helpful information:

WebView 的标准实现无法设置套接字工厂或使其使用给定的套接字.

There is no possibility with the standard implementation of WebView to set a socket factory or to let it use given sockets.

但是可以将完整的应用程序流程绑定到网络.从那时起,这将确保所有新创建的套接字都将绑定到该网络.(设置默认网络的原始方法已在23级弃用,请看下面我的代码中的 bindProcessToNetwork()方法.)

But it's possible to bind the complete app process to a network. This will ensure that from that moment on all newly created sockets will be bound to that network. (The original method to set a default network was deprecated at level 23, just have a look at the method bindProcessToNetwork() in my code below.)

只有运行 API的Android设备才能进行多个网络连接21级或更高级别.

NetworkCallback 可用于侦听满足指定 的任何新连接的网络NetworkRequest .

有了这些知识,我终于找到了一个可行的解决方案:

With this knowledge I was able to finally find a working solution:

ConnectionFragment.java

public class ConnectionFragment extends Fragment {

    private static final String TAG = ConnectionFragment.class.getSimpleName();

    private final NetworkCallback networkCallback = new NetworkCallback();
    private ConnectivityManager connectivityManager;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        Log.v(TAG, "onCreate");
        super.onCreate(savedInstanceState);

        connectivityManager = (ConnectivityManager) getActivity().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    @Override
    public void onStart() {
        Log.v(TAG, "onStart");
        super.onStart();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            registerNetworkCallback();
        }
    }

    @Override
    public void onStop() {
        Log.v(TAG, "onStop");
        super.onStop();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            unregisterNetworkCallback();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void registerNetworkCallback() {
        Log.v(TAG, "registerNetworkCallback");

        final NetworkRequest networkRequest = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .build();

        connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void unregisterNetworkCallback() {
        Log.v(TAG, "unregisterNetworkCallback");
        connectivityManager.unregisterNetworkCallback(networkCallback);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private class NetworkCallback extends ConnectivityManager.NetworkCallback {

        @Override
        public void onAvailable(Network network) {
            Log.v(TAG, "onAvailable");
            bindProcessToNetwork(network);
        }

        @Override
        public void onLost(Network network) {
            Log.v(TAG, "onLost");
            bindProcessToNetwork(null);
        }

        private void bindProcessToNetwork(final Network network) {
            Log.v(TAG, "bindProcessToNetwork: " + network);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                connectivityManager.bindProcessToNetwork(network);
            } else {
                ConnectivityManager.setProcessDefaultNetwork(network);
            }
        }

    }

}

我希望这会对某人有所帮助.

I hope this will help someone.

但是请记住:对于所有依赖于另一个网络的其他连接,您需要手动配置套接字.

But keep in mind: for all other connection relying on another network you need to configure the sockets manually.

最诚挚的问候,
温克勒尔

Best regards,
winklerrr

这篇关于强制WebView在特定网络上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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