gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:40:55 25 4
gpt4 key购买 nike

我有一个 Android 应用程序,它使用嵌入式 PhoneGap WebView。我已经在我的 Activity 上成功实现了 CordovaInterface,应用程序启动并正常运行。

当我暂停应用程序(切换到其他应用程序或按 Tab Home)时,我使用 saveState 方法保存了 WebView 的状态,当应用程序再次启动(此方法适用于没有 PhoneGap 的应用程序)。

但是,当应用程序再次启动时,我尝试在不首先加载 url 的情况下恢复状态(使用 restoreState 方法)(因为我想使用上一个状态)。这会导致错误,因为 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"));
}
}

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

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

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

saveToPreferences(out);
}

关闭/暂停应用程序时出错(已解决 - 请参阅更新 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()?
...

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

这会导致错误,因为 WebView 试图加载一个为空的 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)

更新 1:

这两个错误都已解决,但被新错误取代。

第一个错误是因为 onDestroy() 中的 webView.handleDestroy() 没有被调用。

第二个错误是由于 CordovaWebView 中的字段 baseUrl 未设置。目前我正在尝试通过在 onPause()/onSaveInstanceState() 发生时将上次访问的 url 保存到 SharedPreferences 来解决这个问题:

        String url = webView.peekAtUrlStack();
out.putString("url", url);
webView.handlePause(true);

onResume() 中,我在 SharedPreferences 中加载 url:

    if (savedInstanceState != null) {
webView.restoreState(savedInstanceState);
webView.loadUrlIntoView(savedInstanceState.getString("url"));
}

现在我得到另一个(讨厌的)错误。奇怪的是应用程序立即崩溃(没有通知)。尝试几次后,它还是开始了。这是错误:

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
...

更新 2:

两次恢复WebView状态,出现问题。所以将其从 onResume 中删除。

最佳答案

恢复嵌入式 CordovaWebView 的问题是因为在 onPause()onResume()< 中与 CordovaWebView 的交互onCreate()onDestroy() 未正确发生。开始修复时,restoreState() 发生了两次,导致了进一步的问题。

创建时:

在恢复状态之后,我们需要使用 loadUrlIntoView() 方法设置 CordovaWebView 基本 url:

webView.restoreState(savedInstanceState);
webView.loadUrlIntoView(savedInstanceState.getString("url"));

onDestroy:

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

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

webView.handleDestroy();
}

暂停:

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);
}

恢复时:

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

webView.handleResume(true, false);

结论:

嵌入 CordovaWebView 并保存和恢复其状态是可能的,但是因为您必须了解 DroidGapCordovaWebView< 的很多内部知识,不建议这样做。

希望我的回答对大家有所帮助。

关于java - 在嵌入式 PhoneGap 应用程序中保存和恢复 WebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14233784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com