Friday, 10 June 2011

Configuring an Android Application's WebView Component

I recently started on a new project at work to build out a prototype Android application for one of our clients. I'm using the standard Eclipse IDE, Android SDK and ADT Plugin for Eclipse that the Android team recommends.

During development I came across a couple issues related to the WebView component (which is both a layout and a class) that caused a bit of confusion. In case you're not familiar with it, a WebView component can be embedded into an Activity and allows for the viewing of webpages (essentially it mimics the functionality that exists in the device's built-in browser application). I discovered that the WebView component requires some additional tweaking in order for it to behave in a similar manner to the device's built-in browser. The following are the problems and their solutions that needed to be implemented before the Android prototype worked as required:

:: Enabling Flash Content

When viewing a webpage with embedded Flash video content, a pop-up window would display informing the user that they needed to install the latest Flash plug-in. Even after installing the plug-in via the built-in browser and the Android Market App, the pop-up window still appeared and the Flash content was unable to be played. The phone's built-n browser however was able to play the Flash video content (without any pop-up being displayed).

The solution to this problem was that the WebView component needed to have JavaScript and any plugins explicitly enabled before the Flash video content would play. Here is what I included in my Activity's OnCreate method to explicitly enable both these properties:

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setPluginsEnabled(true)

Note that the webView variable above was previously declared as a private instance variable of type WebView.

:: Initially Rendering in Zoomed Out Mode

When the WebView component loaded and became visible to the user, it arbitrarily rendered a webpage partially zoomed in. This gave a sub-optimal user experience and so the solution was to initially render the webpage in a fully zoomed out mode so that the user could view the whole webpage and decide for themselves if they wanted to perform a pinch gesture to zoom in on a particular area. Again, here is what I included in my Activity's OnCreate method so that the WebView component rendered any webpage fully zoomed out:

WebSettings webSettings = webView.getSettings();
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);

Again note that the webView variable above was previously declared as a private instance variable of type WebView.

:: Forcing WebView to Load all URLs

For a certain subset of URLs that I was trying to load within my WebView component, my application would quit and the phone's internal web browser would launch and load the webpage successfully. I therefore needed to find a solution that would force all URLs to load within my WebView instead of being launched externally on the phone's internal web browser.

The solution entailed creating a CustomWebViewClient class that extended WebViewClient and then wiring up the CustomWebViewClient to handle the shouldOverrideUrlLoading method. This allowed me to force the WebView within my application to render all URLs I was presenting to the user:

private WebView webView = new WebView();
private CustomWebViewClient webViewClient = new CustomWebViewClient();

protected void OnCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    webView.setWebViewClient(webViewClient);
}

private class CustomWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
}

-------------------------------

:: Update

I recently found that the Android developer resources have a tutorial on setting up a WebView correctly. It goes into detail for some (but not all) of the items described above.

Wednesday, 8 June 2011

.NET Code Contracts: Invariants Explained

I have recently started using .NET Code Contracts. I love the streamlined approach to implementing pre-conditions and post-conditions that previously required multi-line if statements along with the ability to check coding assumptions statically and even at runtime (release or debug builds). .NET Code Contracts are another valuable tool in a software engineers arsenal to combat the growing complexity of software systems.

The latest MSDN magazine (June, 2011) has an thorough article on invariants which are an element of .NET Code contracts. The article will go into much more detail but essentially invariants allow for the verification of an object's internal state before and after a set of operations. To create an object invariant, a class simply needs to contain a new private method with the ContractInvariantMethod attribute and then specify any conditions within the private method that should hold true before and after any operation on the class or instances of the class. Here is an example of what the object invariant method would look like for a class called News which has internal state for the Title and Body of a news article:

[ContractInvariantMethod]
private void ObjectInvariant()
{
     Contract.Invariant(!String.IsNullOrEmpty(Title));
     Contract.Invariant(!String.IsNullOrEmpty(Body));
}

What this accomplishes for programmers is that if they inadvertently try to alter the internal state on an instance of the News class to something it should not be (such as setting Title = string.empty), the .NET Code Contract static checker will warn the programmer that they are violating the object's invariant.

Thus, programmers can now design and build classes with the help of .NET Code Contracts that enforce correct API usage. This is a very powerful feature that will avoid subtle bugs from ever occurring.

Friday, 6 May 2011

Technical Debt

:: Definitions

Technical debt is a high-level metaphor used to describe the quality of software source code. It was first introduced by Ward Cunningham back in 1992 and has since take shape in many different forms. Today it can be used informally to describe the state of a software application to a non-technical audience or it can be used more formally for measuring technical aspects related to software source code or specific tasks required to "clean" it up. Given that the term "technical debt" can have a wide array of definitions, the following sources provide some deeper insight about the term: 
A software application is only as good as the team that designs, builds and tests it. Therefore, technical debt has many sources and can be introduced by architects, developers or testers. It usually starts out being just a small issue but if left unmanaged, can grow to become very debilitating for a development team to produce software in a timely manner. Technical debt can be associated at any level of the software application stack whether embedded in the underlying architecture, classes, methods, algorithms, documentation and/or build systems. It is therefore important in software projects to not only know what requirements have yet to be implemented fully but also to know what technical debt lurks within the software so that it can be managed effectively.

:: Measurement

The holy grail for measuring technical debt would be to measure the impact of a single software change in terms of both the value it produces (most likely profitability) and the risk it either increases or mitigates. The ideal software change would maximize overall value while reducing overall risk. As an industry, software development is a very long way from this fine grained approach to measuring technical debt but there are many techniques that can be used (either individually or combined together) to measure the potential burden that a piece of software may have and thus provides some better insight. Like tracking finances you never really know where or how much money is being spent until you keep track of it and the same is true for technical debt... you never really know what software components might need attention or how bad they actually are until you measure them directly.

There are a number of metrics that can be used to measure specific aspects of technical debt across software source code. Unfortunately none of these metrics are able to provide a complete picture of the technical debt for a piece of software but taken together they can provide some key insights into its overall quality. Note that care should be taken to fully understand what a metric is in fact measuring and then to not over-state its importance. I have seen many development teams become religious over certain metrics and subsequently implement policies to stay within some arbitrary bounds. This can often lead to development practises that are detrimental to the actual software being developed. Measuring technical debt is more of an art than a science but quantitative values can still be helpful in the arts.

Here are some of the metrics I have used to measure source code:
  • SLOC (Source Lines of Code): The size of a software application in SLOC isn't a great metric in an of itself, but when used as a comparison mechanism (e.g. the ratio of production code to testing code) it becomes a good indication of relative code quality.
  • Cyclomatic Complexity: A great indication of how complicated the code paths are in a portion of code (usually a method). For methods, it is also a very good indication of how many unit tests are required to effectively traverse and thus test each code path. This is also one of the few metrics statistically correlated with buggy software.
  • Coupling: A number of metrics are defined in this category but of particular interest are fan-in and fan-out metrics which measure the number of calling or called routines for a portion of code.
  • Branch Coverage (Also known as code coverage): Measures the amount of production code that is covered by unit tests. If you think you have tested a method or class sufficiently this is a good metric to observe to verify that thought.
  • Duplicate code: Duplicate code is a particularly interesting metric because the code that is duplicated can in fact be of a high quality. The problems arises when the duplicated code needs to be modified due to a bug. As a result the developer must make sure that each and every occurrence of the bug is fixed otherwise one occurrence of the bug will be fixed but one or possibly many others will remain. A false sense of security that a bug is fixed when it is not can be a disaster in certain contexts.
  • Nested depth level: Some algorithms require nested 'if', 'for' or 'while' statements and an large number of nested statements (also called the depth level) increases the complexity of a portion of code and makes it harder for any one developer to understand it without considerable effort (leading to possibly buggier code).
  • Violations of coding standards: If a coding standard is defined there a usually a number of tools available that either enforce compliance with the standards or simply count the number of infractions.
Apart from simply using metrics to quantify the technical debt of a software application, I have also found the need to capture various software "cleanup" tasks. Anything from dead code to code refactoring to build system improvements can be added to a ticket in your bug tracking system, labelled as "technical debt" and estimated accordingly. By doing this the technical debt within an application can be is tracked over time and observed as it either increases or decreases. It can therefore be managed in a pragmatic way instead of avoided or simply kept unknown.

:: Tooling

There are a whole range of open-source and commercial static analysis software tools available to capture metrics and enforce their compliance:

Tuesday, 19 April 2011

Designing Scalable Systems

Many software based problems with large amounts of persistent data have already, or are currently, out growing the typical design of a single database for all persistence requirements. The need to build scalable software systems is becoming paramount as the amount of data that software applications deal with grows and as we move software applications to the cloud where the addition of more distributed computing power is only an API call away.

Ricky Ho has put together a comprehensive list of general principles and common techniques to use when designing scalable systems. It's a great list to reference while thinking about and designing new components for a software system that is required to scale.

Tuesday, 5 April 2011

Coding the Architecture

I recently found this website called Coding the Architecture. They have an online book full of resources on how to approach, document and refine software architecture. The information contained on the site is simple, concise and backed by some experienced software developers.

One of their ideas/practises I find particularly compelling is what they call 'C4' otherwise known as context, containers, components and classes. The authors highlight the usefulness of decomposing the architecture of an entire software system into 4 separate architecture diagram types. This separation helps development teams understand their software system(s) more clearly by only showing a specific view of them. By reducing the amount of information you put into a single "architecture" diagram, the more easily it is to digest, understand and then act upon.

They also recently blogged about a similar topic in a post called Deliberate practise, effective sketches.