I am attempting to make an Android app that will be paired with an iPhone app - both of which will use WebViews for 90% of their content. Creating a new WebView on both platforms takes a non-zero amount of time - for the iPhone I've had some success creating a WebView before the user taps anything, then adding it to the navigation stack when they do.
I'm trying to do the same with Android but the 'Activity' concept is holding me back. It appears that my WebView has to be part of an Activity, and I cannot render the view without that Activity being the one currently shown on screen. Is this the case? If so, is there no ability to preload a WebView and then insert it into an Activity?
Try looking at the Service concept more than Activity for running background tasks. Webview can be run in a service and that service can be loaded onCreate()
Little bit of background/ similar questions
http://developer.android.com/guide/components/services.html
Android: Using WebView outside an Activity context (The negative comments on the top answer shouldn't affect your question)
Of course. You can add the webview to your layout with the visibility set to View.GONE and make it visible whenever you want.
Related
This question already has an answer here:
How can I display a Progress at start up application in android
(1 answer)
Closed 5 years ago.
I have a heavy user interface that can delay the application load. I want to show an preloader before the UI of activity loaded. note that my ui is in xml file
EDIT:
If you want to load 10 tabs in a view pager, use a FragmentStatePagerAdapter which only loads neighboring tabs(default behavior).
If the heavy UI you specify is only the UI elements, then the app must freeze while loading it. So you'd better show a non-cancelable dialog(without animation) with loading message and after a few moment (like 200ms) load up your UI and explicitly dismiss the dialog.
But if the heavy stuffs is not just UI, maybe some calculations or image processing, just do it in a background thread while showing a dialog with progress and cancel the dialog when the task is done.
#Hassan according to me if on clicking the launcher icon if it takes sometime for your application to render the first screen(perhaps giving a black screen in between). This needs to be corrected in your application.
On the contrary if your applications main screen requires population/retrieval of certain resources for effectively engaging the users, You can possibly do something like a splash screen(outdated) where you do all "population/retrieval" and then simply pass data to your heavy UI.
Now regarding the progress bar if this fetching of data is small, you can give an indeterminate "custom"(some moving animation that would suite your app) progress bar,else if its something like a download you can easily track its progress and show in a horizontal progressbar
You sure can! You are describing a preloader. Here is a nice example of one https://github.com/rtheunissen/md-preloader
You'll have to add more info to your question to get a specific answer, but there are a few basic principles.
You make your life a lot easier if you use a preloader which doesn't show progress of the load, it just goes round and round, because the speed of some load processes can't be measured.
If its a data-load which is taking the time (such as a call to an API), you might want to set a variable for "loading" to true at the top of your script, then when the data has resolved, set it to "false". In your view, have a state or a conditional element which hides / unhides the preloader.
If lots of images are slowing down the page, you might want to look into "lazy-loading" or using "infinite scroll" to only show content when the UI needs to display it on screen.
Thats all the info I can give without more information on the code you have so far. Hope that helps!
I am currently developing an app with many HTML pages to render.
The problem is that Android took about 500ms to start a WebView in my Activity.
i.e.:
I clicked some Button to trigger an WebView to render, in a new Activity.
Android opened another Activity, took about 100ms
Android opened a WebView control, took about 300~500ms.
This WebView starts to load the URL as usual and render the web content.
My question is: how to reduce the bootstrap time for opening a new WebView? ( the step2, but not step 3)
As a comparison, IOS bootstraps the WebView immediately, i.e.: 10ms
Disable all the animation and transition in your app as it makes it slower.
Try not to render too many requests in your controller and pass objects between them instead.
If you are going to show and hide elements according to the result from the database result make all the elements hidden first and then apply visibility then
Use services(directives , etc...) and minimize the code in your controller (they aren't supposed to hold too many code in them )
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.
I'm explaining what I refer to with "app layout".
I'd like to call another app from android but at the same time staying in my own app, this can be visualized with having a border that would be from my own app and inside that border the app I'd like to call would be executing. New app would be then some sort of activity from original app.
The reason for doing this is that we'd like to keep always our app permanent meanwhile we can take advantage of apps that do perfectly some things that our app should do.
I think that if a web layout is possible so should be this, maybe it's not implemented or it would be pretty complicated to do, but it could be done.
Hope someone can guide me with this.
Out of the box - no, that's not possible.
You can call other app activities with startActivityForResult() and have your app re-invoked with result available in onActivityResult() callback when the activity finishes. The called activity will have its own UI and won't display in your app's frame.
If the called activity is your own and you can modify the code, you can make it dialog style with transparent margins/padding that show parts of your calling activity underneath.
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.