Android WebView:向きの変更の処理


147

問題はローテーション後のパフォーマンスです。WebViewはページをリロードする必要がありますが、これは少々退屈な作業です。

毎回ソースからページをリロードせずに向きの変更を処理する最良の方法は何ですか?


3
「ソースからの再読み込み」とは、ページを再度ダウンロードすることですか、それとも単に再レンダリングすることですか?
ジェレミーローガン

Blackhexによって参照されるソリューションは私の問題を解決しました。
Italo Borssatto 2012

6
私のアプリの何がそんなに特別なのか、これらの答えのどれも機能しないのではないかと思います...
RobinJ

回答:


91

WebViewを向きの変更時に再読み込みしたくない場合は、ActivityクラスのonConfigurationChangedをオーバーライドするだけです。

@Override
public void onConfigurationChanged(Configuration newConfig){        
    super.onConfigurationChanged(newConfig);
}

そして、マニフェストでandroid:configChanges属性を設定します。

<activity android:name="..."
          android:label="@string/appName"
          android:configChanges="orientation|screenSize"

詳細については、http//developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChangeをご覧ください。

https://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges


4
私はテストしましたが、機能しないことがわかりました。以下のようにconfigChanges属性を設定すると機能します。android:configChanges = "keyboardHidden | orientation"
virsir

18
以前に何度も言及されているように、実際にはそうすることはお勧めしません
Matthias

3
Matthias:これは本当ではありません-WebViewのJavadocを参照してください。
krtek '17年

このソリューションについて注意する必要がある2つの点:1)WebViewを持つ抽象アクティビティがある場合、configChanges属性はサブクラスアクティビティに追加されます2)アプリが複数のプロジェクトに依存している場合、configChanges属性は依存関係ツリーの最上部(これはActivityクラスを含むプロジェクトではない可能性があります)。
アマンダS

4
このようなonConfigurationChangedメソッドのオーバーライドは役に立ちません。
Miha_x64

69

編集:このメソッドは、ドキュメントに記載されているように機能しなくなりました


元の答え:

これはonSaveInstanceState(Bundle outState)、アクティビティをsaveState上書きしてWebビューから呼び出すことで処理できます。

   protected void onSaveInstanceState(Bundle outState) {
      webView.saveState(outState);
   }

もちろん、webviewが再膨張した後、onCreateでこれを回復します。

public void onCreate(final Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.blah);
   if (savedInstanceState != null)
      ((WebView)findViewById(R.id.webview)).restoreState(savedInstanceState);
}

26
これは方向変更では機能しません—空白の画面が表示されます。saveState \ restoreStateメソッドが呼び出されますが、役に立ちません。
Oleksii Malovanyi

1
次に、onCreateコードスニペットを示します。setContentView(R.layout.webview); mWebView =(WebView)findViewById(R.id.webview); if(savedInstanceState == null){mWebView.getSettings()。setJavaScriptEnabled(true); mWebView.setWebViewClient(new SimpleWebViewClient()); mWebView.loadUrl(Consts.URL_AUTHORIZATION_OAUTH); } else {mWebView.restoreState(savedInstanceState); }
Oleksii Malovanyi

12
saveStateのドキュメントから:このメソッドは、このWebViewの表示データを保存しないことに注意してください。以前の動作により、ファイルがリークする可能性があります...
brillenheini 2013年

5
「してくださいノートこのWebViewのため、この方法は、もはや店の表示データをその」 - developer.android.com/reference/android/webkit/WebView.html
スティーブン・マーク・フォード

WebViewフォームの再読み込みを防ぐために、「このメソッドはこのWebViewの表示データを保存しない」ということについて、何か提案はありますか?
Lucas P.

24

これに対する最良の答えは、見つかったAndroidのドキュメントに従うことです ここにあるです。 基本的に、これにより、Webviewの再読み込みが防止ます

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize|layoutDirection|uiMode"
      android:label="@string/app_name">

必要に応じてonConfigurationChangedアクティビティでオーバーライドすることにより、異常があれば修正できます。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

6
確かにonConfigurationChanged()メソッドは必要ありません。マニフェストの追加属性だけです。私の推測では、これに対するネイティブサポートはWebViewによって提供されたと考えられます。これが、この回答が現在最良のものである理由です(質問が最初に尋ねられたときにこれが機能しなかったため)
Booger

1
onConfigurationChanged()メソッドをオーバーライドする必要のない@Boogerを承認します。manifest.xmlファイルにandroid:configChanges = "orientation | screenSize"を追加するだけです。
-ozanurkan

5

私が使って試したonRetainNonConfigurationInstanceを(返すのWebViewをして戻ってそれを取得し、その後、)getLastNonConfigurationInstanceの間のonCreate、再割り当てしました。

まだ動作していないようです。仕方ないけど、本当に近くにいると思う!これまでのところ、私は空白/白い背景のWebViewを取得しています代わりに。誰かがこれをフィニッシュラインを超えてプッシュするのを助けることができることを期待してここに投稿します。

多分私はWebViewを渡すべきではありません。おそらくWebView内のオブジェクトですか?

私が試した他の方法-私のお気に入りではありません-をこれをアクティビティに設定することです:

 android:configChanges="keyboardHidden|orientation"

...そして、ここではほとんど何もしません:

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  // We do nothing here. We're only handling this to keep orientation
  // or keyboard hiding from causing the WebView activity to restart.
}

これは機能しますが、ベストプラクティスとは見なされない場合があります

一方、回転に応じて自動的に更新する単一のImageViewもあります。これは非常に簡単です。私のresフォルダーの下に、私は横長/縦長のバリエーションを保持する必要がdrawable-landありdrawable-port、次にImageViewに使用R.drawable.myimagenameますのソースとAndroid「正しいことを行います」-イェイ!

...設定の変更を監視する場合を除き、そうではありません。:(

だから私は対立しています。onRetainNonConfigurationInstanceを使用し、ImageViewの回転は機能しますが、WebViewの永続性は機能しません...またはonConfigurationChangedを使用してWebViewは安定したままですが、ImageViewは更新されません。何をすべきか?

最後に、私の場合、強制的な方向付けは許容できる妥協案ではありません。私たちは本当に優雅にローテーションをサポートしたいのです。Androidブラウザーアプリの動作に似ています。;)


7
onRetainNonConfigurationInstanceからビューを返すべきではありません。ビューはアクティビティコンテキストにアタッチされているため、ビューを保存すると、向きが変わるたびにすべての手荷物が引き継がれます。ビューは「リーク」されます。(ここの最後の段落を参照:developer.android.com/resources/articles/…)onRetainNonConfigurationInstanceのベストプラクティスは、ビュー自体ではなく、ビューに必要なデータを保存することです。
Declan Shanaghy、2010

3

妥協の1つは、回転を回避することです。これを追加して、縦向きのみのアクティビティを修正します。

android:screenOrientation="portrait"

これは実際に多くの場合に機能し、私が実装することを決めたソリューションです:-)
Abdo

1
hehe、これは要件の変更です
Max Ch

3

向きの変更を処理し、回転時にWebViewリロードを防止するための最良の方法。

@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}

これを念頭に置いて、方向を変更するたびにonCreate()が呼び出されないようにするには、 android:configChanges="orientation|screenSize" to the AndroidManifest.

あるいは単に ..

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"`

3

マニフェストファイルに次のコード行を書き込むだけです。それは実際に動作します:

<activity android:name=".YourActivity"
  android:configChanges="orientation|screenSize"
  android:label="@string/application_name">

3

私はこれが少し遅れていることに感謝しますが、これは私のソリューションを開発するときに使用した答えです:

AndroidManifest.xml

    <activity
        android:name=".WebClient"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize" <--- "screenSize" important
        android:label="@string/title_activity_web_client" >
    </activity>

WebClient.java

public class WebClient extends Activity {

    protected FrameLayout webViewPlaceholder;
    protected WebView webView;

    private String WEBCLIENT_URL;
    private String WEBCLIENT_TITLE;

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

    @SuppressLint("SetJavaScriptEnabled")
    protected void initUI(){
        // Retrieve UI elements
        webViewPlaceholder = ((FrameLayout)findViewById(R.id.webViewPlaceholder));

        // Initialize the WebView if necessary
        if (webView == null)
        {
            // Create the webview
            webView = new WebView(this);
            webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setBuiltInZoomControls(true);
            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
            webView.setScrollbarFadingEnabled(true);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setPluginState(android.webkit.WebSettings.PluginState.ON);
            webView.getSettings().setLoadsImagesAutomatically(true);

            // Load the URLs inside the WebView, not in the external web browser
            webView.setWebViewClient(new SetWebClient());
            webView.setWebChromeClient(new WebChromeClient());

            // Load a page
            webView.loadUrl(WEBCLIENT_URL);
        }

        // Attach the WebView to its placeholder
        webViewPlaceholder.addView(webView);
    }

    private class SetWebClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.web_client, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }else if(id == android.R.id.home){
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
            return;
        }

        // Otherwise defer to system default behavior.
        super.onBackPressed();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        if (webView != null){
            // Remove the WebView from the old placeholder
            webViewPlaceholder.removeView(webView);
        }

        super.onConfigurationChanged(newConfig);

        // Load the layout resource for the new configuration
        setContentView(R.layout.activity_web_client);

        // Reinitialize the UI
        initUI();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);

        // Save the state of the WebView
        webView.saveState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState){
        super.onRestoreInstanceState(savedInstanceState);

        // Restore the state of the WebView
        webView.restoreState(savedInstanceState);
    }

}

2

あなたは使用して試すことができますonSaveInstanceState()し、onRestoreInstanceState()呼び出すためにあなたの活動にsaveState(...)restoreState(...)あなたのWebViewのインスタンスに。


2

それは2015年であり、ジェリービーン、株式会社、ロリポップ電話でまだ機能するソリューションを多くの人々が探しています。後に多くの苦労私はあなたが向きを変更した後、そのままのWebViewを維持する方法を見つけました。私の戦略は基本的に、別のクラスの別の静的変数にWebViewを格納することです。次に、ローテーションが発生した場合は、Webビューをアクティビティから切り離し、向きが完了するのを待って、Webビューをアクティビティに再接続します。たとえば、最初にこれをマニフェストに配置します(keyboardHiddenおよびキーボードはオプションです)。

<application
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="com.myapp.abc.app">

    <activity
            android:name=".myRotatingActivity"
            android:configChanges="keyboard|keyboardHidden|orientation">
    </activity>

個別のアプリケーションクラスに、次のように記述します。

     public class app extends Application {
            public static WebView webview;
            public static FrameLayout webviewPlaceholder;//will hold the webview

         @Override
               public void onCreate() {
                   super.onCreate();
    //dont forget to put this on the manifest in order for this onCreate method to fire when the app starts: android:name="com.myapp.abc.app"
                   setFirstLaunch("true");
           }

       public static String isFirstLaunch(Context appContext, String s) {
           try {
          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
          return prefs.getString("booting", "false");
          }catch (Exception e) {
             return "false";
          }
        }

    public static void setFirstLaunch(Context aContext,String s) {
       SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(aContext);
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString("booting", s);
            editor.commit();
           }
        }

ACTIVITYに次を追加します。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(app.isFirstLaunch.equals("true"))) {
            app.setFirstLaunch("false");
            app.webview = new WebView(thisActivity);
            initWebUI("www.mypage.url");
        }
}
@Override
    public  void onRestoreInstanceState(Bundle savedInstanceState) {
        restoreWebview();
    }

public void restoreWebview(){
        app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
        if(app.webviewPlaceholder.getParent()!=null&&((ViewGroup)app.webview.getParent())!=null) {
            ((ViewGroup) app.webview.getParent()).removeView(app.webview);
        }
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
        app.webview.setLayoutParams(params);
        app.webviewPlaceholder.addView(app.webview);
        app.needToRestoreWebview=false;
    }

protected static void initWebUI(String url){
        if(app.webviewPlaceholder==null);
          app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
        app.webview.getSettings().setJavaScriptEnabled(true);       app.webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        app.webview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
        app.webview.getSettings().setSupportZoom(false);
        app.webview.getSettings().setBuiltInZoomControls(true);
        app.webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        app.webview.setScrollbarFadingEnabled(true);
        app.webview.getSettings().setLoadsImagesAutomatically(true);
        app.webview.loadUrl(url);
        app.webview.setWebViewClient(new WebViewClient());
        if((app.webview.getParent()!=null)){//&&(app.getBooting(thisActivity).equals("true"))) {
            ((ViewGroup) app.webview.getParent()).removeView(app.webview);
        }
        app.webviewPlaceholder.addView(app.webview);
    }

最後に、単純なXML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".myRotatingActivity">
    <FrameLayout
        android:id="@+id/webviewplaceholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

私のソリューションでは改善できる点がいくつかありますが、たとえば、すでにかなりの時間を費やしています。SharedPreferencesストレージを使用する代わりに、アクティビティが初めて起動されたかどうかを検証する短い方法です。このアプローチにより、Webビューはそのまま(afaik)、テキストボックス、ラベル、UI、JavaScript変数、およびURLに反映されないナビゲーション状態が保持されます。


1
構成の変更を手動で処理するため、WebViewが最初から破棄されないのに、WebViewのデタッチと再アタッチを行う必要があるのはなぜですか?
フレッド

@Fred Cookieを含むWebviewとそのコンテンツの正確な状態、およびWebviewによってロードされたWebページ内のHTML5またはJSで実装されたボタンとチェックボックスの状態を保持したいからです。私が行う唯一の調整はサイズ変更です。
Josh

Fredは、マニフェストでconfigChangesを宣言したため、静的クラスを介してWebViewをデタッチ/再アタッチする必要がないことを意味しました。これにより、回転中にビューとアクティビティが破壊されることはありません。
Eugene Kartoyev

2

あなたがすべき唯一のことはあなたのマニフェストファイルにこのコードを追加することです:

<activity android:name=".YourActivity"
      android:configChanges="orientation|screenSize"
      android:label="@string/application_name">

2

更新:現在の戦略は、Joshのように切り離されたときにWebViewインスタンスを保持されたフラグメントではなくApplicationクラスに移動し、再開時に再接続することです。アプリケーションが閉じないようにするには、ユーザーがアプリケーションを切り替えたときに状態を保持したい場合は、フォアグラウンドサービスを使用する必要があります。

フラグメントを使用している場合は、WebViewのインスタンスの保持を使用できます。Webビューは、クラスのインスタンスメンバーとして保持されます。ただし、親コンテナで破棄されないようにするには、OnCreateViewでWebビューをアタッチし、OnDestroyViewの前にデタッチする必要があります。

class MyFragment extends Fragment{  

    public MyFragment(){  setRetainInstance(true); }

    private WebView webView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       View v = ....
       LinearLayout ll = (LinearLayout)v.findViewById(...);
       if (webView == null) {
            webView = new WebView(getActivity().getApplicationContext()); 
       }
       ll.removeAllViews();
       ll.addView(webView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

       return v;
    }

    @Override
    public void onDestroyView() {
        if (getRetainInstance() && webView.getParent() instanceof ViewGroup) {
           ((ViewGroup) webView.getParent()).removeView(webView);
        }
        super.onDestroyView();
    } 
}

PSクレジットはkcoppockの回答に移動します

'SaveState()'に関しては、公式ドキュメントによれば機能しなくなりました。

このメソッドは、このWebViewの表示データを保存しないことに注意してください。以前の動作では、restoreState(Bundle)が呼び出されなかった場合にファイルがリークする可能性がありました。


setRetainInstanceがフラグメントを保持している間、ビュー(およびWebView)は引き続き破棄されることに注意してください。
フレッド

1
@フレッドその声明の出典を教えてもらえますか?私はこれを、YouTubeページを表示するsetRetainInstance(true)のフラグメントを持つ小さなアプリでテストしました。方向を変更しても、ビデオが中断されないため、ビューは保持されているようです。WebViewが破壊されているようには見えません。
Pinkerton 2016

@Raiそれは単なる誤解でした。それ以来、私は答えを少し編集しました(まだいくつかの文言の修正が必要です)。現在の状況に興味がある場合-この方法は機能します。ただし、問題は、メモリが不足していると、Androidがアプリケーションを強制終了することです。ユーザーが別のアプリケーションでメッセージを読む必要がある重要な入力フォームがあるので、プロセスが強制終了されるのを防ぐために、通知付きのフォアグラウンドサービスを使用する必要がありました。しかし、アンドロイドはまだ活動を破壊し、それゆえ保持されたフレームを破壊します。ただし、Applicationクラスのインスタンスは保持されるため、WebViewをApplicationに移動します。
ボリストロイホフ2016

1
また、MutableContextWrapperをWebViewのベースとして使用し、コンテキストをアタッチとデタッチのアクティビティに切り替えます。Chromiumの組み込みズームコントロールが古いアクティビティへの参照を保存するもう1つの大きな問題なので、アクティビティではなくアプリケーションにWebViewがアタッチされたソリューションはズームインされません。TL; DR; フォームがそれほど重要ではなく、アプリの切り替え後にプロセスが強制終了され、WebViewが復元されない場合は、保持フレームソリューションを使用することができます。PSはまた、私はGoogleの従業員は、これまですべて自分のウィジェット、ガジェットと実生活の問題から、遠く離れていると思います...
ボリスTreukhov

1
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}

これらのメソッドは、どのアクティビティでもオーバーライドできます。基本的に、アクティビティが作成または破棄されるたびに値を保存および復元できます。画面の向きが変わると、アクティビティがバックグラウンドで破棄および再作成されるため、これらのメソッドを使用できます変更中に状態を一時的に保存/復元します。

次の2つの方法を詳しく調べて、ソリューションに適合するかどうかを確認してください。

http://developer.android.com/reference/android/app/Activity.html


1

以前のActivity参照をリークせず、configChanges.. を設定せずにこれを実行するために私が見つけた最良の解決策は、MutableContextWrapperを使用することです

私はこれをここに実装しました:https : //github.com/slightfoot/android-web-wrapper/blob/48cb3c48c457d889fc16b4e3eba1c9e925f42cfb/WebWrapper/src/com/example/webwrapper/BrowserActivity.java


これは副作用なしで確実に機能しますか?この方法に関する情報はあまり見つかりませんでした。
craigrs84 2015

1

これは私にとってうまくいった唯一のものです(私はインスタンスの保存状態を使用しましたonCreateViewが、それほど信頼性がありませんでした)。

public class WebViewFragment extends Fragment
{
    private enum WebViewStateHolder
    {
        INSTANCE;

        private Bundle bundle;

        public void saveWebViewState(WebView webView)
        {
            bundle = new Bundle();
            webView.saveState(bundle);
        }

        public Bundle getBundle()
        {
            return bundle;
        }
    }

    @Override
    public void onPause()
    {
        WebViewStateHolder.INSTANCE.saveWebViewState(myWebView);
        super.onPause();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
        ButterKnife.inject(this, rootView);
        if(WebViewStateHolder.INSTANCE.getBundle() == null)
        {
            StringBuilder stringBuilder = new StringBuilder();
            BufferedReader br = null;
            try
            {
                br = new BufferedReader(new InputStreamReader(getActivity().getAssets().open("start.html")));

                String line = null;
                while((line = br.readLine()) != null)
                {
                    stringBuilder.append(line);
                }
            }
            catch(IOException e)
            {
                Log.d(getClass().getName(), "Failed reading HTML.", e);
            }
            finally
            {
                if(br != null)
                {
                    try
                    {
                        br.close();
                    }
                    catch(IOException e)
                    {
                        Log.d(getClass().getName(), "Kappa", e);
                    }
                }
            }
            myWebView
                .loadDataWithBaseURL("file:///android_asset/", stringBuilder.toString(), "text/html", "utf-8", null);
        }
        else
        {
            myWebView.restoreState(WebViewStateHolder.INSTANCE.getBundle());
        }
        return rootView;
    }
}

WebViewの状態のシングルトンホルダーを作成しました。アプリケーションのプロセスが存在する限り、状態は保持されます。

編集:それloadDataWithBaseURLは必要ではありませんでした、それはちょうどと同じようにうまくいきました

    //in onCreate() for Activity, or in onCreateView() for Fragment

    if(WebViewStateHolder.INSTANCE.getBundle() == null) {
        webView.loadUrl("file:///android_asset/html/merged.html");
    } else {
        webView.restoreState(WebViewStateHolder.INSTANCE.getBundle());
    }

私は読んだものの、必ずしもCookieでうまく機能するとは限りません。


シングルトンの使用は、使用する必要のあるインスタンスが1つしかないことを前提としているため、問題があります。
Android開発者

@androiddeveloperああ。まあ、それがあなたのケースでは当てはまらない場合は、実際にそれが問題です。私はWebViewインスタンスを1つしか持っていなかったので、この質問は思いもよらなかった。
EpicPandaForce 2015年

1

これを試して

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WebView wv;

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

        wv = (WebView) findViewById(R.id.webView);
        String url = "https://www.google.ps/";

        if (savedInstanceState != null)
            wv.restoreState(savedInstanceState);
        else {
            wv.setWebViewClient(new MyBrowser());
            wv.getSettings().setLoadsImagesAutomatically(true);
            wv.getSettings().setJavaScriptEnabled(true);
            wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            wv.loadUrl(url);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        wv.saveState(outState);
    }

    @Override
    public void onBackPressed() {
        if (wv.canGoBack())
            wv.goBack();
        else
            super.onBackPressed();
    }

    private class MyBrowser extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

}

0

このページは私の問題を解決しますが、最初のものを少し変更する必要があります:

    protected void onSaveInstanceState(Bundle outState) {
       webView.saveState(outState);
       }

この部分は私にとってこれに少し問題があります。2番目の方向変更で、アプリケーションはnullポインターで終了しました

これを使用してそれは私のために働きました:

    @Override
protected void onSaveInstanceState(Bundle outState ){
    ((WebView) findViewById(R.id.webview)).saveState(outState);
}

まったく同じようです。なぜ前のものは機能しないのに、2つ目は機能するのでしょうか?
Androidデベロッパー

0

あなたはこれを試す必要があります:

  1. サービスを作成し、そのサービス内にWebViewを作成します。
  2. アクティビティからサービスを開始してバインドします。
  3. ではonServiceConnected方法、WebViewのを取得し、呼び出すsetContentViewあなたのWebViewをレンダリングする方法を。

私はそれをテストしましたが、動作しますが、XWalkViewやGeckoViewなどの他のWebViewでは動作しません。


こんにちは!もっと説明してもらえますか?ありがとう
Jaco

1
さて、あなたのwebviewインスタンスをアクティビティから取得し、その参照をバックグラウンドで実行されているサービスに当てはめてみてください。次にそのアクティビティを開くときは、保存されているWebビューを最初に取得してレンダリングしてみてください。
Ramdane Oualitsen、

0
@Override
    protected void onSaveInstanceState(Bundle outState )
    {
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }

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

解答に説明の行を追加できますか?
yacc

-1

このソリューションが好き http://www.devahead.com/blog/2012/01/preserving-the-state-of-an-android-webview-on-screen-orientation-change/

それによると、WebViewの同じインスタンスを再利用します。ナビゲーション履歴を保存し、構成変更時に位置をスクロールできます。


上記のリンクをクリックすると、「セキュリティプラグイン」をインストールしないと表示できないページが表示されます。避ける。
Allan Bazinet
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.