How not to reload webview on screen rotation? - android

I have a webview which loads content from URL. However, the webview reloads the content on screen rotation, which I would like to avoid.
I have checked similar questions on SO which all recommended either:
Putting orientation into android:configChanges="orientation..." which is generally discouraged and I don't want to use it
Or saving the webview's state with webView.saveState(outState)
As for the 2nd option, the documentation now states:
Please note that this method no longer stores the display data for this WebView. The previous behavior could potentially leak files if restoreState(Bundle) was never called.
Which means that it's not the solution either. Is it possible to solve this?

Related

How to avoid refresh in a webview app with navigation drawer?

So, the thing is that, if I am in a webview on the app and then tap another option of the menu (also in webview) and then go back to the first option this one will refresh the content, I want to avoid that, because if a put a login screen and the user taps another option and goes back they will have the login screen again even if they are already logged.
I already tried this answer but didn't work.
I suspect the problem is that the WebView is not wired into the lifecycle of your activity/fragment and can not distinguish between the first time it is loaded and subsequent times it is loaded. Additionally if the WebView is destroyed (highly probable) the WebView must reload the data.
Ensure that you are saving and restoring the state of your Activity/Fragment correctly and keep track of which webviews are loaded (you can use a HashMap, or boolean or whatever you like). https://developer.android.com/guide/components/activities/activity-lifecycle.html#saras
When you go to load your webviews consult the data from step 1 to determine if you need to reload the content. You may need to pass some data to the HTML to indicate the state (first load etc).

Is it possible to change the context of a WebView after it has been instantiated?

I have a WebView I'm loading in an activity in order to have it preloaded so that it pops up immediately in a different Activity (launched from the first).
The problem is that in order to instantiate a WebView, I have to pass in a Context, in this case it's the first mentioned above.
So it works great, and the second Activity shows the WebView just fine. The problem is that if I click a <select> dropdown in the WebView, its selector dialog shows up UNDER the WebView. It feels like the select doesn't work at all until you hit the back button and briefly see the selection dialog just before you return to the parent activity.
It seems as though when I append the WebView to the layout in the second activity, it's modals get attached to that activity's window, but the WebView itself is attached to the parent activity's window, so it shows in a higher point in the hierarchy.
How can I possibly change the Context of the WebView after it's been instantiated?
This is a very difficult problem to solve -- I have to create the WebViews before the activity is started, but I also need the selection dialogs to work.
Please if anyone can give me some insights here I'd greatly appreciate it.
This is for an SDK project, so I will not have access to the parent activity. Also, saveState isn't working, because the bulk of what is shown in the WebView is generated by JavaScript, and the full DOM stack doesn't transfer.
You can try to create the WebView with a MutableContextWrapper:
MutableContextWrapper mMutableContext=new MutableContextWrapper(context);
WebView mWebView=new WebView(mMutableContext);
and later on you could do
mMutableContext.setBaseContext(newcontext);
But ...
WebView is a very complex component that will probably be using the passed context to create other objects like Handlers. WebView probably uses those handlers to post stuff to the original UI thread, so at the end you'll probably have a View with a mix of contexts, you know, a double memory leak (if it ever works properly)
Webview spans at least 1 thread "webcore" that is where the action happens and is also in constant communication with the original UI thread with ... handlers? through the original context? who knows!
There are even 2 different webview engines: Kitkat is chromium-based while jelly bean and previous versions use AOSP/WebView. So you have an additional breaking point.
The reasons you state are not strong enough imho. WebView is not that slow. If the app you load is, try to optimize it. There are a lot of things you can do for that, like loading the HTML & graphics from internal assets.
In my App (it's browser) I have the same problem. I don't like to load WebView every time when user back to App. And I've solved this problem partially. I've overridden onBackPressed() on my HomeActivity and use moveTaskToBack(true) instead of super.onBackPressed(). So when user use system back on HomeActivity it does't destroy Activity and all views. It just minimize the App. Visually it's the same behavior but if user try to run App by launch icon, all views already loaded. I know it's temporary solution and all views can be destroyed by system any time but it gives quite good result. And covers a lot of cases for me.

How to cache WebView content in Android?

In my Android app I need to cache the (already loaded) content of WebView on pause and then restore it on resume. I wonder how can I do this?
It is cached automatically unless you disable. Nothing special needs to be done.
A common problem is that badly designed parent resets the view itself in methods like onStart or onResume, forcing to reload the contents. You need to be careful with the view in these methods, it may already with content.

WebView, Splash Screen and performance

I've got WebView within an Activity that loads content from the network. When the WebView starts loading I launch another activity to act as a Splash Screen that I hide when the WebView is done loading.
I found out when testing that the same web page takes longer to load when I add a splash screen than when I don't. So I assume there's a network thread whose priority drops when the activity containing the WebView goes to the background. How do I control that thread to keep the WebView fast?
I found the setRenderPriority method of the WebSettings class, I'm not sure what it does and I don't know what is the "Render thread" it talks about. I tried :
getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
but it didn't have any effect on the loading time.
Thanks to anyone who can help me out.
I'm not directly answering your question, but rather suggesting an alternative... starting another activity to simply provide a splash screen could be rather expensive. Instead, you might consider extending the layout that contains your WebView to place a RelativeLayout at the WebView's level, and make your WebView a child of that layout. Additionally, you can place an ImageView (or whatever you need for your splash) within the same RelativeLayout, and you can set its visibility to invisible when you don't want it displayed.

Trigger or Force Redraw or Re-Render of WebView

My understanding is that WebView's PictureListener.onNewPicture() is called whenever the already loaded page finished rendering (or re-rendering in case certain events make the WebKit engine re-calculate page layout).
I also (think that I) understand that those WebView renders are controlled internally in WebView and ordinarily I wouldn't care how they are being generated.
However, for a certain function in my app, I need to trigger an extra PictureListener.onNewPicture() without re-loading the url (i.e. no reload() or loadUrl()).
Essentially, what I am looking for is a function like repaint() or redraw() or some other mechanism that only generate one more PictureListener.onNewPicture() and that's it (without the slowness and overhead associated with re-loading data).
Is there a way to achieve this?
Try using the requestLayout() function.
not sure if it will do what you want, but it worth a try.

Categories

Resources