Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent WebView reloads in FragmentPagerAdapter?

I have a FragmentPagerAdapter used to show about 6 tabs, all of which load their data from a web server. One of the tabs contains a WebView that loads an image from my server. The server side costs of generating the image are high, and thus I want to reduce the number of calls to reload the WebView. For the non-WebView tabs, I have been able to save my state (for those, just a simple array) and restore them as tabs get swiped through.

Problem:

  • WebView reloads every time I swipe back to it using FragmentPagerAdapter, leading to high reload times and high load on my web server.

Solutions Considered:

  • Use ViewPager.setOffscreenPageLimit() This is problematic because it will force more tabs to be loaded, even if they are never going to be viewed. This is needlessly expensive on my server.
  • Use WebView.saveState() and WebView.restoreState() The documentation has been updated to make it clear display state is no longer maintained here, so this is no longer useful for this scenario.
  • Set my activity to have: android:configChanges="keyboardHidden|orientation|screenSize" This works for the rotation case, but doesn't affect the ViewPager/FragmentPagerAdapter swiping through tabs case.

It sounds like the old behavior of WebView.saveState() would have been perfect...

like image 454
RealCasually Avatar asked Jan 27 '13 21:01

RealCasually


1 Answers

The problem appears to be that you are wiping out your own results.

While you need a new WebView on a configuration change, you do not need a new WebView otherwise. And, if you already have the WebView, you do not have to tell it to do anything.

So, I'd try this:

  • Hold onto the WebView that you create in onCreateView() in a data member of the fragment
  • Only inflate the layout in onCreateView() if that data member is null
  • Only call loadUrl() if you inflated the layout

(if you are creating the WebView in Java code, replace "inflate the layout" with "create the WebView via its constructor")

If the contents of the fragment is more than the WebView, you will also need to hold onto the root view that you inflated in a data member, so you can return that from onCreateView().

like image 153
CommonsWare Avatar answered Sep 30 '22 17:09

CommonsWare