Android WebView之间的sessionStorage数据共享

叨叨

Android中,每个WebView实例都有自己独立的sessionStorage存储空间,使用不同的WebView实例加载新的网页是无法共享sessionStorage数据的。

原理很好理解,每个WebView都相当于一个Web Broswer,session生命周期是与Browser的使用周期同步的-随Browser的打开而创建,随Browser的关闭(实例销毁)而销毁。

在移动web混合开发中,很多采用多页面多Activity+WebView一对一组合的加载方案,这样非单页面复用WebView的方案,想使用sessionStorage就得谨慎了。

方案

如果想在新的WebView实例中设置sessionStorage数据以实现共享效果,可以通过使用WebViewClient类中的shouldInterceptRequest方法来实现。该方法会在WebView加载资源时被调用,可以在其中设置sessionStorage数据。

代码示例:

private WebView webView1;
private WebView webView2;

// 在onCreate()方法中初始化第一个WebView实例
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 初始化第一个WebView
    webView1 = findViewById(R.id.web_view_1);
    webView1.getSettings().setDomStorageEnabled(true);
    webView1.loadUrl("https://example.com");
}

// 在另一个方法中加载新的WebView并共享sessionStorage数据
private void loadNewWebView() {
    // 初始化第二个WebView
    webView2 = new WebView(this);
    webView2.getSettings().setDomStorageEnabled(true);
    webView2.setWebViewClient(new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            // 在sessionStorage中设置上一个web页面的sessionStorage数据
            view.evaluateJavascript("sessionStorage.setItem('key', 'value');", null);
            return super.shouldInterceptRequest(view, request);
        }
    });

    // 加载第二个网页
    webView2.loadUrl("https://example.com/newpage");
}

那么问题来了,上一个web页面的sessionStorage数据怎么取?
要用到WebView的evaluateJavascript()方法,代码示例:

// 获取sessionStorage数据
private void getSessionStorageData() {
    webView.evaluateJavascript("sessionStorage.getItem('key');", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            // 获取到的数据,可以把数据存入静态对象中,以便其它webview设置sessionStorage数据
            Log.d("TAG", "Session storage data: " + value);
        }
    });
}

进阶

很多时候Android端并不知道甚至不想知道H5端的key数据,只想一股脑获取后透传给别的webview,该怎么做呢?

Android的WebView没有提供直接访问sessionStorage的API,那只能骚操作了~~

使用JavaScript代码将sessionStorage的数据转换为JSON字符串,然后通过evaluateJavascript()方法获取该字符串,最后使用Android中的JSON解析器将其转换为一个JSON对象,代码示例:

// 在另一个方法中获取sessionStorage数据
private void getSessionStorageData() {
    // 执行JavaScript代码获取sessionStorage数据并将其转换为JSON字符串
    webView.evaluateJavascript(
        "(function(){return JSON.stringify(sessionStorage);})();",
        new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                // 使用JSON解析器将JSON字符串转换为JSON对象
                try {
                    JSONObject sessionStorageJson = new JSONObject(value);
                    // 获取到全部数据,可以把数据存入静态变量中,以便其它webview设置sessionStorage数据
                    Log.d("TAG", "Session storage data: " + sessionStorageJson.toString());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    );
}

需要注意,evaluateJavascript()方法是异步执行的,onReceiveValue()可能未被及时调用,因此瞅好时机调用该js很重要,另外也要处理好未被调用带来的问题。

© 版权声明
THE END
喜欢就支持以下吧
点赞17 分享
评论 共1条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片
    • 热门评论
      cheny的头像-乘月网钻石会员cheny等级-LV6-乘月网作者0