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

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).

Related

How not to reload webview on screen rotation?

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?

Android Navigation Component: prevent configChanges of single fragment

I'm tyring to implement the new Android Navigation Components in my andorid app, and I've moved from a multi-activity logic, to a single activity with multiple fragments approach, as suggested by google.
One of my screens (used to be an activity, now is a fragment) renders a WebView that loads an HTML string (may contain Videos, twitter/instagram embeds and text), along with some other views (image galeries). My main problem is that when the user rotates the phone, the webview starts loading from the begining, and loses the user's scroll position. After searching, I've decided that handling configChanges manually for this particular fragment is the correct way to go, instead of letting android reload the whole fragment, since saving and restoring the WebView's state does not seem to work properly.
However, since I've moved to a single activity approach, if I do this, I'll have to handle configChanges manually for my whole app, which I do not want to do.
Is there a way to only handle configChanges manually in a single fragment, or should I move this fragment to its own activity, as it used to be, and add the configChanges code only there?

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.

Change default Activity dynamically

I want to be able to change which Activity is run when the user runs the application.
I know how to do this in the application's manifest file, but I would like to do it programmatically after install. The reason being, I want the user to be able to choose which screen loads when he opens the application.
How can I do this? The only way I know of seems very clunky: have an essentially empty Activity which has the MAIN intent-filter - which then reads the user's settings and transfers the user to the desired Activity. This creates a lot of mess, like the back-stack needs to be considered, and the overheads of loading one activity straight after another seems wasteful of time and resources.
You cannot change launcher activity dynamically.
As you said it is possible by saving user preferences and start desired activity each time. I have tried it and it is fast enough to not show itself. Don't remember to call finish on main activity. it will solve back stack problem.
Also you can use different fragments for different activities and decide which one should be added to main activity. It may be faster. However as I said it is fast enough to start a new activity and hide main activity because it is done in onCreate method. Don't worry about that.

When to use saveInstanceState() method?

I know saveInstanceState() is used to store activity variables, text in EditText, etc.
But I have a doubt that should I save state of view?
Let me give you a scenario. My view has 3 buttons. On clicking one of them, a WebView is displayed to user (in same activity). Now if app gets killed, should I save state that user was displayed WebView when app got killed and when activity gets recreated display WebView instead of buttons?
Other scenario is, I have 3 tabs in view. Selecting each tab shows different view. As explained in above case again should I save that user has last selected this tab?
It will be best if you can explain the cases where I should and should not save activity state.
The operating system knows when it should re-create your app's previous state (the screen orientation changed or your app was killed in the background by the OS) and when to create a new instance (the user left your app with the back button). The onRestoreInstanceState() method is only called when there's a state to restore (when the system is restoring a previous state, as opposed to creating a new instance of the activity).
The short answer, then, is that if you override onSaveInstanceState() and onRestoreInstanceState(), the system will call them when appropriate, and you don't have to worry about deciding when you "should" save state.
When overriding onSaveInstanceState(), yes, you should save everything about your activity's state. This is the method being used during screen orientation change. Think about it - if you rotate your phone, do you expect the current app to change tabs, or the screen that just opened to disappear?
For more information, see the Android documentation on recreating an activity.
I have not done very much research on savedIntanceState on app gets killed. But yes you may save maybe a integer variable (referring to which button is clicked) in state, so that when activity is recreated, you know which webview used to be shown (or none). Same goes to your second situation.
Some extra use case of saved instance state:
One of the most used scenario is during user switches orientation, say you have a couple of edit texts on screen, their holding texts would be gone if user change his device orientation. Saved instance state helps you to recover the entered texts.
Another situation is you will most likely have a few class variable in your activity, probably used to save what user has done, or some temporary list object in a list activity. Saving those variables also prevents you from needing to recover the data on orientation change.

Categories

Resources