【问题标题】:Does WebView saveState() preserve Javascript variables/environment?WebView saveState() 是否保留 Javascript 变量/环境?
【发布时间】:2013-02-27 02:28:33
【问题描述】:

我搜索了很多主题,但仍然找不到我的问题的答案。我正在开发一个使用WebViewAndroid 应用程序。

我使用onSaveInstanceState()onRestoreInstanceState() 来保存WebView 状态,如下所示:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    webView.saveState(savedInstanceState);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    webView.restoreState(savedInstanceState);
}

我的onCreate()也有这个:

public void onCreate(Bundle savedInstanceState) {
    ... other code ...
    if(savedInstanceState != null){
        webView.saveState(savedInstanceState);
    }else{
        webView.loadUrl("http://mypage");
    }
}

问题:似乎恢复WebView 根本不会恢复Javascript 变量/环境/工作区。当应用程序在后台被杀死然后恢复时,整个 Javascript 和所有对象/变量都消失了。 javascript 代码是名称间隔的,即window.utilitiesPackwindow.eventHandlerswindow.automation 等,它们是未定义的。还使用了JQuery 和其他 javascript 插件:恢复状态后它们似乎都未定义。基本上整个Javascript都没有恢复。

有人可以确认或反驳它的真实情况(Javascript 未保存)吗?如果没有保存整个 Javascript 工作区,那么 WebView.saveState() 究竟保存了什么?是否有一些简单/优雅的方式来使用现有 API 来保留 Javascript 对象?

//============================================== =========

Update1:​​所以问题依然存在。最大的困难是:

我正在启动相机Intent 以获得结果。拍照后,应用程序会返回到WebView 活动,并且应该使用 Javascript 使用一些数据变量来更新 HTML5 LocalStorage

带有WebView 的主Activity 在显示Camera Activity 时被杀死,所以当我们回到WebView 时,不再有Javascript,也没有我可以从Android 代码调用的函数。这在Galaxy S3 上每次都会发生。它仍然发生在其他手机上,但并非每次都在拍照时发生。

不知道在这里做什么。不知何故,我必须使用 WebView 制作主 Activity 以在使用 Camera Intent 拍摄图片时保留状态。有谁知道如何实现这一点?

【问题讨论】:

  • “有人可以确认或反驳它的真实情况吗” - 您不是只是通过尝试确认了这一点并看到确实发生了什么吗?
  • (文档似乎暗示保存的是WebBackForwardList。)
  • “您不是只是通过尝试确认了这一点,然后看到确实会发生这种情况吗?”我简直不敢相信整个 Javascript 都没有保存。我希望我不理解某些东西,因为如果是这样的话,这对于使用具有复杂 javascript 功能的网页的应用程序来说就是一个限制。
  • 我理解对了吗:WebBackForwardList 实际上保存了 Javascript 的东西?
  • 嘿@user2113581,这是更多人遇到的问题。您能否为自己的问题写一个解决方案,而不是您在下面留下的评论?

标签: javascript android variables webview savestate


【解决方案1】:

正如 user2113581 评论的那样,将 WebView 移动到应用程序的上下文而不是 Activity 是一个潜在的解决方案。这仍然存在 user2113581 提到的所有缺陷,包括 <select> 不起作用(因为它创建了一个窗口,但应用程序上下文没有窗口令牌)。

我已经扩展了我的应用程序来管理我的 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);
  }
}

最后,在您的 Activity 中,您需要在有意义的生命周期事件期间将 mWebView 添加到容器视图(FrameLayout 或类似)中。当活动暂停或停止时,您需要将其从容器中删除。我使用onResumeonPause 效果很好。

【讨论】:

  • 聪明!你是否也为 iOS 尝试过类似的策略?
  • 这只是部分解决方案,因为 Android 操作系统有权在另一个应用程序(例如相机应用程序)中完全终止您的应用程序进程,因此在应用程序实例上保存 webview 状态不会解决此问题。例如,当系统资源不足时,就会发生这种情况。
  • 我发现这种方法的一个问题是Webview 现在有一个ApplicationContext 而不是ActivityContext。这工作正常,直到您尝试从 JavaScript 调用“confirm(...)”,然后应用程序将崩溃。似乎当 Webview 必须弹出一个对话框时,它试图将上下文强制转换为 ActivityContext 并且此实现失败。
  • 为此,您还需要将android:name="fully.qualified.package.name.MyApplication" 添加到AndroidManifest.xml 中的<application> 标记中。有关示例,请参见 this answer
【解决方案2】:

找到的信息很少,只有这一行:

请注意,此方法不再存储此 WebView 的显示数据。如果从不调用 restoreState(Bundle),则之前的行为可能会泄漏文件。

还有这一行:

返回用于保存状态的后退/前进列表的相同副本。

WebView.saveState(Bundle) 的 javadoc 中。

【讨论】:

  • 感谢您的回复。自从我遇到这个问题以来已经有一段时间了,所以我在这里忘记了我的问题。我将您的答案标记为正确,因为它是正确的。对于那些遇到同样问题的人:我解决它的方法是在 App 的上下文中而不是在 Activity 的上下文中定义 webView。现在一切都按预期工作。这种方法的唯一问题是您必须覆盖 onJsAlert() 和 onJsConfirm() 才能让 alert()/confirm() 正常工作。
  • 这只是部分解决方案,因为 Android 操作系统有权在另一个应用程序(例如相机应用程序)中完全终止您的应用程序进程,因此在应用程序实例上保存 webview 状态不会解决此问题。例如,当系统资源不足时,就会发生这种情况。
猜你喜欢
  • 1970-01-01
  • 2020-02-16
  • 2021-01-01
  • 2013-09-23
  • 2012-01-27
  • 1970-01-01
相关资源
最近更新 更多