WebView saveState()是否保留Javascript变量/环境?
我搜索了很多线索,仍然找不到我问题的答案。我正在开发一款使用WebView saveState()是否保留Javascript变量/环境?,javascript,android,variables,webview,savestate,Javascript,Android,Variables,Webview,Savestate,我搜索了很多线索,仍然找不到我问题的答案。我正在开发一款使用WebView的Android应用程序 我使用onSaveInstanceState()和onRestoreInstanceState()保存WebView状态,如下所示: @Override public void onSaveInstanceState(Bundle savedInstanceState) { webView.saveState(savedInstanceState); } 及 我的onCreate()中也
WebView
的Android
应用程序
我使用onSaveInstanceState()
和onRestoreInstanceState()
保存WebView
状态,如下所示:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
webView.saveState(savedInstanceState);
}
及
我的onCreate()
中也有这个:
问题:恢复WebView
似乎根本无法恢复Javascript
变量/环境/工作区。当应用程序在后台被杀死,然后被还原时,整个Javascript和所有对象/变量都消失了。javascript代码以名称分隔,即window.utilitiesPack
,window.eventHandlers
,window.automation
,等等,它们是未定义的。另外还使用了JQuery
和其他javascript插件:在恢复状态之后,所有这些插件似乎都未定义。基本上,整个Javascript都没有恢复
有人能证实或反驳这是事实吗(Javascript没有保存)?如果不保存整个Javascript工作区,那么
WebView.saveState()
save到底保存什么?是否有一些简单/优雅的方法来使用现有的API来保存Javascript对象
//======================================================
更新1:因此问题仍然存在。最大的困难是:
我正在启动一个摄像头Intent
以获取结果。拍照后,应用程序返回到WebView
活动,应该使用Javascript使用一些数据变量更新HTML5LocalStorage
当显示摄像头活动时,WebView
的主要活动被终止,因此当我们回到WebView时,不再有Javascript,也没有可以从Android代码调用的函数。这在Galaxy S3上每次都会发生。这种情况在其他手机上也会发生,但不是每次拍照都会发生
我不知道该怎么办。不知何故,我必须使用WebView进行主要活动,以便在使用相机拍摄照片时保持状态。有人知道如何做到这一点吗?找到的信息很少,只有这一行: 请注意,此方法不再存储此WebView的显示数据。如果从未调用restoreState(Bundle),以前的行为可能会泄漏文件 这一行: 返回用于保存状态的后退/前进列表的相同副本
在javadoc for.中,正如user2113581所评论的,将WebView移动到应用程序的上下文而不是活动中是一个潜在的解决方案。这仍然存在user2113581提到的所有缺陷,包括
不工作(因为它创建了一个窗口,但应用程序上下文没有窗口标记)
我已经扩展了我的应用程序来管理我的webview
MyApplication.java:
public class MyApplication extends Application {
private WebView mWebView;
private boolean mWebViewInitialized;
// ...
@Override public void onCreate() {
super.onCreate();
mWebView = new WebView(this);
mWebViewInitialized = false; // we do some initialization once in our activity.
}
public WebView getWebView() { return mWebView; }
public boolean isWebViewInitialized() { return mWebViewInitialized; }
public void setWebViewInitialized(boolean initialized) {
mWebViewInitialized = initialized;
}
}
在我们的活动中:
@Override protected void onCreate(Bundle savedInstanceState) {
// ...
MyApplication app = (MyApplication) getApplication();
mWebView = app.getWebView();
if (!app.isWebViewInitialized()) {
/* first time initialization */
app.setWebViewInitialized(true);
}
}
最后,在您的活动中,您需要在有意义的生命周期事件期间将
mWebView
添加到容器视图(FrameLayout或类似视图)。当活动暂停或停止时,需要将其从容器中删除。我使用了onResume
和onPause
,效果很好。“有人能证实或反驳这是真的吗”-你不是刚刚通过尝试并看到确实发生了什么来证实这一点吗?(文档似乎暗示保存的是WebBackForwardList
)“你不是刚刚通过尝试并看到确实发生了什么来证实这一点吗?“我简直不敢相信整个Javascript都没有保存。我希望我没有理解一些东西,因为如果是这样的话,这对使用带有复杂javascript功能的网页的应用程序来说是一个很大的限制。我理解对了吗:WebBackForwardList
实际上保存了javascript内容?嘿@user2113581,这是一个越来越多人都遇到的问题。你能为你自己的问题写一个解决方案而不是你在下面留下的评论吗?谢谢你的回复。我已经有一段时间没有遇到这个问题了,所以我忘了我的问题。我认为你的答案是正确的,因为它是正确的。对于那些遇到同样问题的人:我解决这个问题的方法是在应用程序上下文中定义webView,而不是在活动上下文中定义webView。现在一切正常。这种方法的唯一问题是必须重写onJsAlert()和onJsConfirm(),才能使alert()/confirm()工作。另外,将不再工作,所以实现您自己的html选择。除此之外,它工作完美,js不会丢失。这只是一个部分解决方案,因为Android操作系统有权在另一个应用程序(如摄像头应用程序)中完全终止您的应用程序进程,因此在应用程序实例上保存webview状态无法解决此问题。例如,当系统资源不足时,可能会发生这种情况。聪明!您是否也尝试过类似的iOS策略?这只是一个部分解决方案,因为Android OS有权在另一个应用程序(如摄像头应用程序)中完全终止您的应用程序进程,因此在应用程序实例上保存webview状态无法解决此问题。例如,当系统资源不足时,就会出现这种情况。我发现这种方法的一个问题是,Webview现在有一个ApplicationContext而不是ActivityContext。在您尝试从JavaScript执行“confirm(…)”调用之前,这一切都很正常,然后应用程序将崩溃。当Webview必须弹出对话框时,它似乎试图将上下文强制转换为ActivityContext,但此实现失败。
public class MyApplication extends Application {
private WebView mWebView;
private boolean mWebViewInitialized;
// ...
@Override public void onCreate() {
super.onCreate();
mWebView = new WebView(this);
mWebViewInitialized = false; // we do some initialization once in our activity.
}
public WebView getWebView() { return mWebView; }
public boolean isWebViewInitialized() { return mWebViewInitialized; }
public void setWebViewInitialized(boolean initialized) {
mWebViewInitialized = initialized;
}
}
@Override protected void onCreate(Bundle savedInstanceState) {
// ...
MyApplication app = (MyApplication) getApplication();
mWebView = app.getWebView();
if (!app.isWebViewInitialized()) {
/* first time initialization */
app.setWebViewInitialized(true);
}
}