叨叨
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很重要,另外也要处理好未被调用带来的问题。
- 最新
- 最热
只看作者