66

アクティビティBを呼び出すアクティビティAがあります。アクティビティBでは、ボタンをクリックすると、finish()が呼び出され、次にアクティビティBのonDestroy()が呼び出され、アクティビティAに戻ります。

Androidのドキュメントによると、onDestroyが呼び出される前に、onSaveInstanceState(Bundle bundle)が呼び出されます。ここで、次のようにします。

@Override
    public void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);
        System.out.println("Saving webview state");
        Log.d(TAG, "In onsave");
        wv.saveState(outState);

    }

次回アクティビティBがアクティビティAから開始されるとき、

oncreate()で、私は次のことを行います。

onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

if(savedInstanceState != null){
//restore webview
}else {
// code
}
}

ただし、アクティビティBでonDestroyを呼び出す前に、onSaveInstanceStateメソッドが呼び出されることはありません。これに関するどんな助けも大いに感謝されるでしょう。

編集:これが不可能な場合。Webビューの状態を保存する方法があるかどうか教えてください

4

5 に答える 5

346

私も同じような状況でした。それは明らかに開発バグでした。間違った方法を上書きしました:

public void onSaveInstanceState(Bundle outState, 
                                PersistableBundle outPersistentState)

代わりに正しいもの:

protected void onSaveInstanceState(Bundle outState)
于 2015-11-19T11:01:53.843 に答える
60

onRestoreInstanceState()アクティビティが再作成されるときに呼び出されることに注意してください。ただし、次の場合に限ります。

それはOSによって殺されました。「このような状況は、次の場合に発生します。

  • デバイスの向きが変わります(アクティビティが破棄されて再作成されます)
  • あなたの前に別のアクティビティがあり、ある時点でOSはメモリを解放するためにあなたのアクティビティを強制終了します(たとえば)。次回あなたがあなたの活動を始めるとき、あなたonRestoreInstanceState()は呼ばれます。」

したがって、アクティビティ中にデバイスの[戻る]ボタンfinish()を押すと、アクティビティが編集され、次にアプリを起動したときに再度開始されます(再作成されたように聞こえますね)が、今回は保存されません戻るボタンを押したときに意図的に終了したため、状態になります。

于 2012-10-09T05:33:48.363 に答える
9

こちらのドキュメントをご覧ください:http: //developer.android.com/reference/android/app/Activity.html

永続データはライフサイクルコールバックの一部ではないため、onPause() 代わりに保存することが重要であることに注意してください。そのため、ドキュメントで説明されているように、すべての状況で呼び出されるわけではありません。onSaveInstanceState(Bundle)

onSaveInstanceStateメソッドのドキュメントには、次のように書かれています。

onPause()このメソッドを、アクティビティがバックグラウンドに配置されているときや破棄に向かう途中で常に呼び出される、または破棄の前に呼び出されるなどのアクティビティライフサイクルコールバックと混同しないでください onStop()onPause()このメソッドではなく、 が呼び出された場合の1つの例はonStop()、ユーザーがアクティビティBからアクティビティAに戻る場合 onSaveInstanceState(Bundle)です。特定のインスタンスは復元されないため、Bを呼び出す必要はないため、システムはそれを呼び出さないようにします。onPause()呼び出された場合と呼び出されなかった場合の例は、アクティビティBがアクティビティAの前に起動された場合です。システムは、Aのユーザーインターフェイスの状態がそのまま維持されるため、Bの存続期間中に強制終了されない場合、アクティビティAのonSaveInstanceState(Bundle)呼び出しを回避できます。 onSaveInstanceState(Bundle)

これを試して:

@Override
public void onPause(){
   System.out.println("Saving webview state");
    Log.d(TAG, "In onsave");
    wv.saveState(outState);
    super.onPause();

}

and
@Override
 public void onResume(){
     //restore webview
 }

そのifステートメントの目的はわかりませんが、これを試して、何が起こるかを確認してください。

于 2012-10-09T05:04:13.363 に答える
3

最終的には、バック/履歴を永続ストレージに書き込む必要があります。一例としてデバイスがシャットダウンされている場合、および呼び出しonSaveInstanceStateonPause行う(私の意見では)不自然な例を回避する場合(必要なバンドルを取得するために必要なことを実行してからonRestoreInstanceState渡すことができます)にrestoreState)。

したがって、デザインを再検討する以外に(ユーザーがアプリケーションを閉じて、ブラウザーを作成していない場合、ユーザーは本当に同じ履歴を保持したいのでしょうか?)、SharedPreferencesそれらの使用方法を調べてください。

残念ながら、バンドルを共有設定に入れることはできません。また、を介してバンドルを作成することもお勧めしませんParcelable(IPC専用であり、永続ストレージではありません)。しかし、あなたができることは、バンドルが保存するすべてのプリミティブを保存することです。これも考案されているかもしれませんが、永続的なストレージを取得する唯一の方法のように思えます。

次に、SharedPreferencesに格納されているプリミティブを介してバンドルを再構築し、それをに渡しrestoreState()ます。Androidのソースコードをチェックして、webView.saveState()実際に何が行われるかを確認できます(2.1コードを調べたところ、int、シリアル化可能なオブジェクト、SSL証明書の別のバンドルが記述されているようです。SSL証明書バンドル自体は4つの整数です) 。頭のてっぺんから、できる限りすべてのプリミティブを書き込んでから、シリアル化されたデータを書き込むローカルファイルの場所(文字列)も保存します。

BackForwardリスト全体の順序付けられたコレクションがある場合でも、それをに変換してそれらの値goBack()を使用する方法がわかりません(リストへのアイテムの追加に関係する保護されたメソッドがありますが、それにアクセスすることはできません)。goForward()を使用しない限りrestoreState()、バンドルを正しく再構築するためにすべての作業を行うのはそのためです。

真面目な話ですが、私の検索スキルがひどい(完全に可能)場合を除いて、あなたの仕事WebViewができる場所を超えて履歴を保存するsaveInstanceState/restoreInstanceStateことは、多くの人が遭遇した問題ではないようです。つまり、ユーザーがアプリケーションを明示的に閉じたときにWebViewの履歴を保持しようとしている人はそれほど多くないので、なぜこれを行っているのかを自問する必要があります。

この情報を永続的に保存してWebViewにリロードする本当に簡単な方法がある場合は、お詫びします。

于 2012-10-09T07:42:24.580 に答える
0

呼び出しonSaveInstance方法については、

public void onSaveInstanceState(Bundle outState)

値を保存するために使用する必要はありません

public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState)
于 2019-10-27T15:16:17.203 に答える