在嵌入式PhoneGap应用程序中保存和恢复WebView

asg*_*oth 6 java android android-webview cordova

我有一个Android应用程序,它使用嵌入式PhoneGap WebView.我已经成功实现CordovaInterface了我的活动,应用程序启动并运行它应该如何运作.

当我暂停应用程序(切换到其他应用程序或标签主页)时,我WebView使用saveState方法保存状态,应用程序再次启动时应该恢复(此方法适用于应用程序PhoneGap).

然而,当应用程序再次启动时,我尝试恢复状态(使用restoreState方法)而不首先加载URL(因为我想使用最后一个状态).这会导致错误,因为PhoneGap期望加载一个url(至少这是我从异常中收集的内容).

我的问题是:如何在嵌入式PhoneGap WebView中正确保存和恢复WebView的状态?

我的onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    webView = (CordovaWebView) findViewById(R.id.webView);

    if (savedInstanceState == null) {
        savedInstanceState = restoreFromPreferences();
    }
    if (savedInstanceState == null) {
        webView.loadUrl("file:///android_asset/www/index.html");
    } else {
        webView.restoreState(savedInstanceState);
        webView.loadUrlIntoView(savedInstanceState.getString("url"));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的onPause方法(类似的逻辑onSaveInstanceState):

@Override
protected void onPause() {
    super.onPause();

    Bundle out = new Bundle();
    webView.saveState(out);

    saveToPreferences(out);
}
Run Code Online (Sandbox Code Playgroud)

关闭/暂停应用程序时出错(已解决 - 请参阅更新1):

当我关闭应用程序时,我收到错误.这可能是相关的,但我不知道如何:

01-09 11:44:50.181: E/ActivityThread(2068): Activity my.package.MainActivity has leaked IntentReceiver org.apache.cordova.NetworkManager$1@a6bc4020 that was originally registered here. Are you missing a call to unregisterReceiver()?
01-09 11:44:50.181: E/ActivityThread(2068): android.app.IntentReceiverLeaked: Activity my.package.MainActivity has leaked IntentReceiver org.apache.cordova.NetworkManager$1@a6bc4020 that was originally registered here. Are you missing a call to unregisterReceiver()?
...
Run Code Online (Sandbox Code Playgroud)

再次启动应用程序时出错(已解决 - 请参阅更新1):

这会导致错误,因为WebView尝试加载一个null的url:

01-09 11:38:22.813: E/AndroidRuntime(1979): FATAL EXCEPTION: main
01-09 11:38:22.813: E/AndroidRuntime(1979): java.lang.NullPointerException
01-09 11:38:22.813: E/AndroidRuntime(1979):     at java.lang.String.indexOf(String.java:994)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at org.apache.cordova.CordovaWebView.loadUrlNow(CordovaWebView.java:499)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at org.apache.cordova.CordovaWebView.loadUrl(CordovaWebView.java:384)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at org.apache.cordova.CordovaWebViewClient.onPageFinished(CordovaWebViewClient.java:298)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:327)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at android.os.Looper.loop(Looper.java:137)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at android.app.ActivityThread.main(ActivityThread.java:4745)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at java.lang.reflect.Method.invokeNative(Native Method)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at java.lang.reflect.Method.invoke(Method.java:511)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-09 11:38:22.813: E/AndroidRuntime(1979):     at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

更新1:

两个错误都已解决,但由新错误替换.

第一个错误是因为webView.handleDestroy()onDestroy()当时不叫.

所述第二误差是由于场baseUrlCordovaWebView其中未设置.目前我正在尝试通过将最后访问的URL保存到发生SharedPreferences时来解决这个onPause() / onSaveInstanceState()问题:

        String url = webView.peekAtUrlStack();
        out.putString("url", url);
        webView.handlePause(true);
Run Code Online (Sandbox Code Playgroud)

onResume(),我加载网址SharedPreferences:

    if (savedInstanceState != null) {
        webView.restoreState(savedInstanceState);           
        webView.loadUrlIntoView(savedInstanceState.getString("url"));
    }
Run Code Online (Sandbox Code Playgroud)

现在我得到另一个(讨厌的)错误.奇怪的是,应用程序立即崩溃(没有通知).经过几次尝试后,无论如何都会启动.这是错误:

01-09 15:11:19.869: A/libc(3392): Fatal signal 11 (SIGSEGV) at 0x00000008 (code=1), thread 3404 (WebViewCoreThre)
01-09 15:11:19.925: I/ActivityManager(281): Displayed my.package/.MainActivity: +197ms
01-09 15:11:19.973: I/DEBUG(86): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-09 15:11:19.973: I/DEBUG(86): Build fingerprint: 'generic/vbox86tp/vbox86tp:4.1.1/JRO03L/eng.dan.20121106.232935:userdebug/test-keys'
01-09 15:11:19.973: I/DEBUG(86): pid: 3392, tid: 3404, name: WebViewCoreThre  >>> my.package <<<
01-09 15:11:19.973: I/DEBUG(86): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000008
01-09 15:11:20.249: I/DEBUG(86):     eax 00000000  ebx b6b61c98  ecx 00000000  edx 00000001
...
Run Code Online (Sandbox Code Playgroud)

更新2:

恢复WebView状态发生了两次,这导致了问题.所以删除它onResume.

asg*_*oth 10

与恢复嵌入的问题,CordovaWebView是因为与相互作用CordovaWebViewonPause(),onResume(),onCreate()onDestroy()没有正确地发生.当开始修复时,restoreState()发生了两次,这引起了进一步的问题.

的onCreate:

在恢复状态旁边,e需要使用方法设置CordovaWebView基本URL loadUrlIntoView():

webView.restoreState(savedInstanceState);
webView.loadUrlIntoView(savedInstanceState.getString("url"));
Run Code Online (Sandbox Code Playgroud)

的onDestroy:

我们需要执行handleDestroy()清理所有与PhoneGap相关的东西,比如PluginManager,广播接收器......:

@Override
public void onDestroy() {
    super.onDestroy();

    webView.handleDestroy();
}
Run Code Online (Sandbox Code Playgroud)

在onPause:

onPause(),我们存储CordovaWebView的状态.我们查找最后一个注册的URL并将其存储在中SharedPreferences.另外,handlePause()需要调用.

@Override
protected void onPause() {
    super.onPause();

    String url = webView.peekAtUrlStack();
    webView.handlePause(true);

    Bundle out = new Bundle();
    webView.saveState(out);
    out.putString("url", url);

    saveToPreferences(out);
}
Run Code Online (Sandbox Code Playgroud)

的onResume:

onResume()我们需要调用CordovaWebViewhandleResume():

webView.handleResume(true, false);
Run Code Online (Sandbox Code Playgroud)

结论:

嵌入CordovaWebView并保存和恢复其状态是可能的,但是因为您必须知道来自DroidGap&的许多内部CordovaWebView,所以不建议这样做.

我希望我的回答能帮到别人.