Suppose I want to write an app for Android OS that is not going to be a real-time game; that is, it will be a turn based game (requiring internet access) that is based on forms and pages.
I'd like to use HTML5 to do this, and simply have a WebView on the native app with some bindings to the website's javascript, etc. for more functionality (if needed). Of course, since this is not a realtime game, performance doesn't seem like it would be an issue.
The only real reason I can think of to not use HTML5, is because there would be loading times in between forms e.g. every time a user clicks on a button to perform an action that transitions them to a new form, which is actually a new web page, that web page must be loaded. If I did this natively using the Android SDK, the loading of the forms would be seamless and instantaneous (even though the web up/down will take a small amount of time, but that is expected).
Is this a real issue? Are there ways around it that don't involve using the Android SDK instead of HTML5?
A couple of ideas:
1) Bundle your HTML with the app in the folder called assets and load it from there with an URL like file:///android_asset/your_path.html. This will reduce the time required to load because the content will be on the device.
However, beware of the following webview bug in Android 3.0+ that causes any URL with # or ? to fail to load from the assets folder:
http://code.google.com/p/android/issues/detail?id=17535
2) You can also choose to use AJAX to reduce the page load time. You load the heavy libraries once in the beginning and then use AJAX for subsequent page loads to avoid loading a lot of JS stuff. But beware of the bug above, since AJAX page loads use # in the URL.
Related
I'm building a 3rd party library in Android that works on WebViews and analyzes their performance.
From the work done so far, I found that some Ad servers bring up Banner ad WebViews, and auto-refreshes the ad every X seconds.
During the auto-refresh, I noticed they replace the HTML content with a new ad, rather than creating a new WebView instance.
I need to catch these reloads without interfering with JS injections.
I would expect to have some kind of a setOnDomChangedEventListener method, but I couldn't find one.
What technique can I use to catch these events?
First of all, reloads and DOM changes are different things. A page can change DOM without loading anything. A reload of a page re-initializes DOM and JS context from scratch, so it's not the same as a dynamic update of the DOM tree.
If you want to listen to network loads, you need to use WebViewClient.shouldInterceptRequest callback in WebView.
Listening to DOM changes is not possible via WebView Java API. One way to do that is to inject your code into the page and use MutationObserver (doc). Just be aware that if the page reloads, you will need to re-inject the code.
A less intrusive but more involved way is to use remote Web Debugging. The debugging protocol WebView uses supports DOM breakpoints. Actually, if you are building a performance analyzing framework, that might be a good approach, as it will allow you to measure and monitor lots of things. But be aware that due to security considerations, in order for an Android app to connect to the remote debugging socket, it needs to run either as shell user (as adb), or be signed with the same key as the target app.
I have installed an Ionic app (beta 14) on my Android (Lollipop) device using:
ionic platform add android
ionic run android
I have also manually built the app and installed it with adb.
The app uses ion-side-menus, and the animations for the transitions between simple views (list -> detail -> detail) are incredibly laggy on a capable phone. The animation when the side menu slides out is very smooth in contrast.
To further investigate the situation, I served the www directory from my dev machine and opened that page in Chrome on the phone and it was as smooth as one would expect. The app also runs smoothly on iOS devices.
Does anyone have any clues as to why it is so slow when the app is in Ionic, but performs as expected when it is just being rendered in the browser?
I faced with the same issue. It's worse in cases that you need to load a lot of information. In those occasion, I disable the transition effect by setting:
nav-transition=none
if you need to disable the transition from your controller, do the following:
app.controller('ctrl', function($scope,$state, $ionicViewSwitcher){ $scope.goBack = function(){
$ionicViewSwitcher.nextTransition('none');
$state.go('back');
});
I found some solutions by which I face problem in ionic app transitiosn..
After State Change I use this code..
//OnState Change..
$scope.$on('$stateChangeSuccess', function() {
$ionicLoading.show();
MyTeamListing();
})
which hit serve every time when i change state.. which is slow down the app.
i just Remove first line and my code is working fine...
I don't know it is a good or bad way but its working for me fine..
Transaction is become slow if too much data is load on transaction
so that I use ionic events which load data after transaction done.
$scope.$on('$ionicView.afterEnter', function(){
console.log("afterEnter");
$ionicLoading.show();
loadRemoteData();
$ionicLoading.hide();
});
Well, the perks of developing hybrid application is its code re-usability and faster development however, what advantage we get on development results in slow hybrid apps. We can make the application relatively faster if we follow following points:
absolutely remove the comments and unnecessary functions
minimize the white-space, make your functions as small as possible
use minified css and js
optimize the images, the fewer the images the faster the application
if possible, preload the images check here
keep the nonessential js file to the bottom of the page just before the end of body tag
remove the unnecessary pages, unnecessary scrolling and large pages.
limit the usage of input boxes; make use of radio buttons,checkboxes and comboboxes if possible.
don't use jquery library unless of utmost necessity, use javascript
First, a disclaimer: i'm completely new to iphone, android or any mobile development. In the other side, i've been developing websites (php, javascript) for long time.
I have a website which is adapted for mobile and works great. But, there are some features i need such as prevent the screen from dimming (my site is designed to be used for many hours without user interaction while being permanently visible or for example being able to send notifications (with sound, etc., to attract user attention)).
This has lead me to consider a webview. From what i've seen, it's about creating a native app which just a webview (browser without toolbars) and using html and javascript to operate. It will use some native functions to perform some native actions (such as the ones i want).
I've searched around and i don't have a specific response to this: can i tell a webview to, permanently load the content from a remote site ? i mean, my site is php based (zend), with many jquery content manipulation. Can i tell him something like LOAD htp://www.mysyite.com and let him do everything else from it ? absolutely no local content applies, everything is remote. The webview would just be an "interface" to the website.
And additional question is: can i use jquery on it ? ajax calls ? geolocation ? i mean, in a browser i can, i just wonder if inside a webview i can.
I've read that phonegap does this. But most of the time, when taking about phonegap and about webview i general, i read people talking about loading locally the page not remotely in a permanent basis.
Finally, yes, i will build a native app in the future. But now, i simply don't have time to learn about android, ios and blackberry at the same time. Thanks a lot for your responses.
For Android only:
Can i tell him something like LOAD htp://www.mysyite.com and let him do everything else from it ? absolutely no local content applies, everything is remote. The webview would just be an "interface" to the website.
Yes, of course you can. Suppose you have a webview in an activity (it's really easy), you would load the web page something like:
WebView myWebView = .... // get a reference from XML or if you just created get its ref
myWebView.loadURL("http://www.mysite.com");
I would start with this API Guide article. Also, taken from WebView JavaDoc:
A WebView has several customization points where you can add your own behavior. These are:
Creating and setting a WebChromeClient subclass. This class is called when something that might impact a browser UI happens, for instance, progress updates and JavaScript alerts are sent here (see Debugging Tasks)
Creating and setting a WebViewClient subclass. It will be called when things happen that impact the rendering of the content, eg, errors or form submissions. You can also intercept URL loading here (via shouldOverrideUrlLoading()).
Modifying the WebSettings, such as enabling JavaScript with setJavaScriptEnabled().
Injecting Java objects into the WebView using the addJavascriptInterface(Object, String) method. This method allows you to inject Java objects into a page's JavaScript context, so that they can be accessed by JavaScript in the page.
Please be also aware that the webview is not that powerful as the phone's browser. Here is a SO thread where a friend posted an interesting question. You might find helpful the answers he got.
This app already exists in the Apple App store and Android markets. It is an app that uses a lot of native code and is not a candidate to be fully html5ed.
Longwinded Description
I want to have a Web-based series of settings pages. Some of these pages will live locally on the mobile device, and some will be hosted on a remote server. The native app will need to communicate with the local web pages to get and set information in the webpage using javascript.
For instance, the first page shown in the WebView/UIWebview will be a local index page. If the remote website is down, the links on the index page to the remote pages will be greyed out. On loading the WebView, the native app will need to detect the reachability of that page and send javascript to the page to grey out the buttons. Likewise, some settings changes made in the local web pages need to be sent back to the Native app for processing.
Short and Sweet Requirements Summary
Embed remote and local webpages in a webview
Theses webpages will be the same for both Android and iOS
Local pages use JavaScript to get data from and send data to the Native Mobile App
Potential Solution Pathways
A. PhoneGap
I realize that Phonegap would work well for this if my application was entirely a web app. From my reading it seems like Phonegap doesn't really like to be embedded in a native app for part time work.
What? You say it's really easy and I've been grossly misinformed? Enlighten me oh wise one.
B. Roll My Own
I'm open to rolling my own solution, however the methods for getting and setting information via Javascript from the Webviews to the Native Apps seems quite disparate. More-so the getting than the setting (bogus URLs for iOS, very nice AddJavaScriptInterface for Android). Also, it seems like this path could lead to a severe maintenance headache in the future.
Say what? Your genius programmer friend has made a website describing this process in excruciating detail? Tell me more.
C. 3rd Party Library
The perfect 3rd party library that does everything I want (and more!) exists? Save me from my ignorance.
Decision
In the future, it seems like PhoneGap's 'Cleaver' project will be the best way to do this.
Since it's not ready for Android yet, it seems that the current (Early June '12) best solution for write-once-embedded-HTML is to use a fake URL scheme to communicate from the web page to the native app (both platforms can execute JS on the page directly when going from native app to web page).
For Android this is simpler to do. Take a look at WebView's addJavascriptInterface method. You can create your own object with methods that can be called directly in the HTML javascript.
iOS requires a bit of trickyness. Best solution for these types of problems is a couple things:
For callbacks to iOS you will need to basically make up your own URL scheme like native://somehost.com/somepath When your javascript wants to inform the iOS code use window.location = 'native://somehost.com/somepath';
Set the UIWebView delegate to an object that defines webView:shouldStartLoadWithRequest:navigationType: it will look something like this
if ([request.URL.scheme isEqualToString:#"native"]){
if([request.URL.host isEqualToString:#"somehost.com"]) {
//Do the code you need to do here, branch off depending
//on the path and/or host, you can parse parameters here too
return NO; //This will keep UIWebView from trying to actually load
//your made up scheme
}
}
return YES; //If the request isn't one you want to intercept return YES/true
//so UIWebView will load the page
To have your iOS code send information or call functions in your javascript you can use WebView's stringByEvaluatingJavaScriptFromString:. This will return the result of a javascript expression so you can also use it to get some information from the page itself. To call a function use something like this
[webview stringByEvaluationgJavaScriptFromString:#"myJavaScriptFunction();"]
You can also handle the made up scheme in Android by creating a custom WebViewClient and overriding the shouldOverrideUrlLoading method similarly to the iOS code above except the return calls are backwards, you return true if you handled the URL and the WebView should do nothing more, and false if you want the WebView to handle loading. Be sure to create and assign the custom WebViewClient to the WebView using setWebViewClient. To call javascript functions on the actual WebView do something like webview.loadUrl("javascript:myJavaScriptFunction();");
PhoneGap iOS has a concept called Cleaver where you can embed the web view into a native iOS app. Randy McMillian has a good example here. On the Android side work is being done to bring the same functionality. So we are not there yet but we will get there.
In my application, i have some external urls to load, for which i am using a custom webview. but the performance of this webview is very very slow. If i open the same url in native android browser, it works fine. but in the webview, it just takes a lot of time to load the page.
Is there anyway that the performance of a webview can be enhanced in terms of loading a webpage time? Help is always appreciated.
Usama, WebViews will be little slower than the browser as here every activity has to have a callback to the Android app layer.
Having said that, see if you can disable javascript (if it's not used in your app) and more importantly check the caching behavior in the webview that has been set.
WebSettings has some methods related to caching like - setAppCacheEnabled, setAppCacheMaxSize, setCacheMode etc.
setDatabaseEnabled, javascrpt, loadImagesAutomatically are other properties that might impact the load time.