android - Handling screen rotation in WebView -


my web app works great in chrome handles configuration changes (such screen rotation) excellent. preserved.

when loading web app webview in android app web app loses state on screen orientation change. partially preserve state, i.e. preserves data of <input> form elements, javascript variables , dom manipulation gets lost.

i webview behave way chrome does, i.e. preserving state including javascript variables. should noted while chrome , webview derives same code base chrome not internally use webview.

what happens on screen orientation change activity (and eventual fragments) gets destroyed subsequently recreated. webview inherits view , overrides methods onsaveinstancestate , onrestoreinstancestate handling configuration changes hence automatically saves , restores contents of html form elements back/forward navigation history state. state of javascript variables , dom not saved , restored.

proposed solutions

there have been few proposed solutions. of them non-working, preserving partial state or in other ways suboptimal.

assigning webview id

webview inherits view had method setid can declared in layout xml file using android:id attribute in declaration of <webview> element. necessary state saved , restored, state partially restored. restores form input elements not javascript variables , state of dom.

onretainnonconfigurationinstance , getlastnonconfigurationinstance

onretainnonconfigurationinstance , getlastnonconfigurationinstance deprecated since api level 13.

forcing screen orientation

an activity can have screen orientation forced setting screenorientation attribute <activity> element in androidmanifest.xml file or via setrequestedorientation method. undesired breaks expectation of screen rotation. deals change of screen orientation , not other configuration changes.

retaining fragment instance

does not work. calling method setretaininstance on fragment retain fragment (it not destroyed), hence instance variables of fragment preserved, does destroy fragment's view hence webview gets destroyed.

manually handling configuration changes

the configchanges attribute can declared activity in androidmanifest.xml file android:configchanges="orientation|screensize" handle configuration changes preventing them. works, prevents activity getting destroyed hence webview , contents preserved. has been discouraged , said used last resort solution may cause app break in subtle ways , buggy. method onconfigurationchanged gets called when configchanges attribute set.

mutablecontextwrapper

i heard mutablecontextwrapper can used, haven't evaluated approach.

savestate() , restorestate()

webview have methods savestate , restorestate. note accoriding documentation savestate method no longer stores display data webview whatever means. either way these methods not seem preserve state of webview.

webviewfragment

the webviewfragment convenience fragment wraps webview can going less boilerplate code, listfragment. not additional state preserving preserve state.

question

is there real solution problem of webview getting destroyed , losing state upon configuration changes? (such screen rotation)

a solution fully preserves state including javascript variables , dom manipulation. solution clean , not built on hacks or deprecated methods.

after researching , trying out different approaches have discovered have come believe optimal solution.

it uses setretaininstance retain fragment instance along addview , removeview in oncreateview , ondestroyview methods prevent webview getting destroyed.

mainactivity.java

public class mainactivity extends activity {     private static final string tag_fragment = "webview";      @override     protected void oncreate(final bundle savedinstancestate) {         super.oncreate(savedinstancestate);          webviewfragment fragment = (webviewfragment) getfragmentmanager().findfragmentbytag(tag_fragment);         if (fragment == null) {             fragment = new webviewfragment();         }          getfragmentmanager().begintransaction().replace(android.r.id.content, fragment, tag_fragment).commit();     } } 

webviewfragment.java

public class webviewfragment extends fragment {     private webview mwebview;      public webviewfragment() {         setretaininstance(true);     }      @override     public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) {         view v = inflater.inflate(r.layout.fragment_webview, container, false);         linearlayout layout = (linearlayout)v.findviewbyid(r.id.linearlayout);         if (mwebview == null) {             mwebview = new webview(getactivity());             setupwebview();         }         layout.removeallviews();         layout.addview(mwebview, new linearlayout.layoutparams(viewgroup.layoutparams.match_parent, viewgroup.layoutparams.match_parent));          return v;     }      @override     public void ondestroyview() {         if (getretaininstance() && mwebview.getparent() instanceof viewgroup) {             ((viewgroup) mwebview.getparent()).removeview(mwebview);         }         super.ondestroyview();     }      private void setupwebview() {         mwebview.loadurl("https:///www.example.com/");     } } 

Comments

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -