6

埋め込みを使用する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"));
    }
}

私の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が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)

更新1:

両方のエラーは解決されましたが、新しいエラーに置き換えられました。

最初のエラーは、webView.handleDestroy()inonDestroy()が呼び出されなかったためです。

2番目のエラーは、フィールドが設定されていないことが原因baseUrlでしCordovaWebViewた。現在、最後にアクセスしたURLを発生SharedPreferences時に保存することで問題を解決しようとしています。onPause() / onSaveInstanceState()

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

onResume()、URLをロードしますSharedPreferences

    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状態の復元が2回発生したため、問題が発生しました。から削除しましたonResume

4

1 に答える 1

10

埋め込みの復元に関する問題は、、、、およびとの相互CordovaWebView作用が正しく行われなかったためです。修正を開始すると、restoreState()が2回発生し、さらに問題が発生しました。CordovaWebViewonPause()onResume()onCreate()onDestroy()

onCreate:

状態を復元する次に、メソッドを使用してCordovaWebViewベースURLを設定する必要がありますloadUrlIntoView()

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

onDestroy:

handleDestroy()PluginManager、ブロードキャストレシーバーなど、PhoneGapに関連するすべてのものをクリーンアップするために実行する必要があります...:

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

    webView.handleDestroy();
}

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

onResume:

で'sonResume()を呼び出す必要があります:CordovaWebViewhandleResume()

webView.handleResume(true, false);

結論:

を埋め込み、その状態を保存して復元することは可能ですが、 &CordovaWebViewから多くの内部情報を知る必要があるため、そうすることはお勧めできません。DroidGapCordovaWebView

私の答えが誰かに役立つことを願っています。

于 2013-01-09T19:38:50.300 に答える