January 22, 2014

Today Software Magazine: The Making of the Android App

The arrival of Today Software Magazine back in March 2012 infused life into the IT community in Romania. It provided voice to the many talented IT and software development professionals who were looking for a common platform to showcase their expertise, share best practices, and find solutions to various problems impacting the industry.

Today Software Magazine has grown in strength from its first issue of four articles to the latest issue, #17, which is comprised of twelve contributions on topics like agile continuous improvement, Scrumban (a combination of Scrum and Kanban), and the real-time web.

At 3Pillar, we are proud to have been associated with Today Software Magazine pretty much from the start. As we wrote about previously, members of our team in Romania managed to develop the iPhone and iPad apps for Today Software Magazine in six weeks flat. Building on the success of the iPhone/iPad app, our development team started working on the Today Software Magazine Android application.

The Beginning of the Process

After hearing of the potential opportunity for development of an Android app for Today Software Magazine from Dan Suciu (Director Engineering – Cluj), the Android competency center team in India led by Anjula Pahuja and Vineet Aggarwal started working on the scope of the Android version. A team of 3 people (Ravindra Prajapati, Khushboo Kaur, and Priyanka Singh) was created to deliver the project.

3Pillar Team

The 3Pillar team of Software Engineers followed our usual Adaptive Product Lifecycle Methodology (Adaptive PLM) and created 3 sprints of 2 Weeks each. The role of the Sr. Technical Lead (Vineet Aggarwal) was instrumental in adhering to the set timelines identified for each of these sprints, helping the team technically, and providing status reports on progress to both the client and management. As per our Adaptive PLM approach, each sprint has a specific “theme,” and the team showcased a demo to the client at the end of each sprint to get their input and further improve the delivery in subsequent builds.

Project progress was tracked closely using JIRA, and all the respective tasks were created as user stories and assigned to the respective developer in JIRA to keep track of the development time and completion date. GitHub was selected as the code repository tool, and a development branch was created for developers at the start of Sprint 1. To avoid any conflicts, the master branch was merged with the development branch at the end of each sprint and tagged with subsequent sprint versions following code review.

Based on discussions with the client, the team was told to complement the iPhone app’s design and features. We were also encouraged to come up with our own suggestions. Here is the set of features that were proposed and implemented:

  • Refresh functionality:  On subsequent launches, we suggested there could be two ways to inform users about new content. One would have been using push notifications, which would let app users know that new content is available via text message. The second option was to provide a manual Refresh functionality, which would enable users to make the decision to check for new content. As per business requirements, the refresh functionality was chosen, and it enables users of the app to check for new versions of the magazine whenever available.
  • Sharing on Social Networks: We got an additional requirement to share each issue’s URL on Facebook and Twitter. We suggested that the client use 3PillarLabs’ SocialAuth Android library, which helped them to share content on social networks even if the user has not installed Facebook or Twitter on their devices.
  • Application support for devices running back to Android GingerBread 2.3.3, as by the time of development it still accounted for more than 20% of Android OS market share as per the latest statistics from the Android Developer site. Further, we suggested to port the app to 7’’ tablets, as a large percentage of Android users use them.

Application Overview and Architecture

The application starts with a splash screen and provides options to the user to make their language selection between English and Romanian. On clicking the language button, the app starts retrieving the image of the latest issue and articles from the TSM web server. It then downloads the data saved in internal memory and a SQLite database.

TSM Android App

After downloading the information pertaining to the latest issue, the app launches the home screen and shows the TSM home screen with all the downloaded issues and articles. On clicking the action bar menu icon, a user can open the left navigation drawer that contains list of issues downloaded from server. In the right panel screen it will show the list of articles from the selected issue.

Clicking on any article will open the TSM article viewing screen, where a user can read the full article and details of author. On clicking the share icon, the app launches a pop-up menu with options to share articles via Facebook, Twitter, or email. The language selection can be changed by clicking settings from the action bar. Once the new language change is selected, the app will erase all the stored data and restart to download content in the new selected language format.

The technical architecture of the app is shown in the diagram below.

TSM app

Tools and Libraries Used

We used the following tools and libraries to build the application over the course of 6 weeks:

  • Eclipse: The Eclipse IDE was chosen as the application development tool due to the developers’ familiarity with it.
  • Charles Proxy:  This tool help us during API testing and checking the iPhone app flow.
  • SocialAuth Android Library: The API enables user authentication and sharing updates through different various social networks and hides all the intricacies of generating signatures & tokens. SocialAuth is used for the sharing of articles on social networks and mail.
  • Android-app-v7-appcompat: Action bar support comes in Android 4.0. This library supports the Android action bar implementation in Android lower versions. Implementing the action bar removes the dependency on the Android option button.
  • i3P Android:  Developed by 3Pillar Labs, this library helped us to create the custom left navigation bar for our use case.

Challenges

The following sections highlight the challenges faced by the team during development and testing. It tells how we identified the problems at hand and what it took to solve the problem.

Bitmap Optimization

The TSM home screen showed a list of articles from the selected issue along with author bitmaps. The team found that the images received from the server need to be downsized in order to avoid users an OutOfMemory error, as it resulted in application crashing in some user scenarios.

Solution

To effectively handle the OutOfMemory issue, we used bitmap sampling, a process to develop a downsize image from an existing image. The major challenge was to maintain the aspect ratio of the original image, thereby retaining the quality of image during its re-sizing. Presented below is sample code to calculate the image sample size:

Calculate image sample size

public  int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		final int height = options.outHeight;
		final int width = options.outWidth;
		if(height= 0) {
			options.inJustDecodeBounds = false;
			options.inSampleSize = sampleSize;
			
			if(haveNetworkConnection(activity.getBaseContext())){
				try{
					imageResponse=new HttpRequest(activity.getBaseContext()).getHttpInputStream(imagePath); //FileNotFoundException, MalformedUrlException
				}catch(IOException e){
					e.printStackTrace();
					if(e instanceof SocketException || e instanceof SocketTimeoutException){
					}
					return null;
				}
				if(imageResponse!=null){
					Bitmap bmp = BitmapFactory.decodeStream(imageResponse, null, options);
					if(bmp==null)
						return null;
					saveToInternalSorage(bmp, activity,id);
					return bmp;
				}
			}
		}
		return null;
	}

YouTube Video Play

Many articles received from the TSM server contain embedded YouTube videos. Playing YouTube videos inside a web view is a very challenging task, because you don’t have controls on web view. Also, the implementation varies on devices for Gingerbread and Ice Cream Sandwich devices. For instance, in Gingerbread devices, the YouTube videos used to run by default on full-screen, whereas in Ice Cream Sandwich and above, device users have to manually enable the full screen.

Solution

We considered separate approaches for Gingerbread and ICS devices. For GingerBread, we used the Android default Videoview control, whereas for ICS and above devices we made use of the Java reflection API to seamlessly play the videos. Using the reflection API, we get the reference of HTML5VideoFullScreen$VideoSurfaceView from WebKit and play the full screen video. For both the versions, sample code is pasted below:

YouTube video in Android 2.3.3

VideoView customVideoView = (VideoView) customViewContainer.getFocusedChild();
Field mUriField = VideoView.class.getDeclaredField("mUri");
mUriField.setAccessible(true);
Uri uri = (Uri) mUriField.get(customVideoView);

Android 4.0 and above

Class _VideoSurfaceView_Class_ = Class.forName("android.webkit.HTML5VideoFullScreen$VideoSurfaceView");
java.lang.reflect.Field _HTML5VideoFullScreen_Field_ = _VideoSurfaceView_Class_.getDeclaredField("this$0");
_HTML5VideoFullScreen_Field_.setAccessible(true);
Object _HTML5VideoFullScreen_Instance_ = _HTML5VideoFullScreen_Field_.get(((FrameLayout) view).getFocusedChild ());

Improving App performance

Fetching TSM data in an asynchronous manner in the application and then showing the data on the UI was taking 20-25 minutes. This is definitely a large time. To reduce the complexity, a number of different processes were created. Each of them was doing its own task of downloading data from the server. The difficult part in this is the synchronization among them and avoiding any conflict. Author images cannot be downloaded until the Author information is downloaded, for example, as the path of the image is contained in the Author information. Thus, the challenge was to optimize the data downloading time and thereby improve the application’s performance.

Solution

We implemented ThreadPoolExecutor to cut down on the response time. All the tasks are attached with the executor. Initially, the thread pool was created with size as 2 allowing two threads to execute in parallel. As soon as these threads finish, the threads from the pool are queued to download the content as the user browses the application.

ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 2,60, TimeUnit.SECONDS, new ArrayBlockingQueue(2), threadFactory);
executorPool.execute(new LoadIssueImages(handler, language,getBaseContext()));
executorPool.execute(new LoadIssueArticles(handler, language,getBaseContext()));
executorPool.execute(new LoadAuthorInformation(handler,language, getBaseContext()));
executorPool.execute(new LoadAuthorImages(handler, language,getBaseContext(), this));

Testing

The app was tested for the following devices: Nexus 4 (Android 4.3), Nexus 7 (Android 4.1,  7’’ tablet), HTC Desire (Android 2.3.3, 480×800), Samsung Tab (7″ and 10″ tablets), and a Samsung Galaxy Y (240×320).

We selected these devices to cover the major range of Android devices in the market based on our experience. The testing team used the following set of testing methodologies to ensure that the app experience should not break while in use.

  • First Time App Launch Testing: When the mobile app is installed successfully an app icon will be created. On tapping the App icon, the splash screen is displayed.
  • API Testing: We verified the iPhone app flow using the Charles Proxy tool. The idea is to provide the same user experience as we have in iOS.
  • Network Scenario Testing:  We verify the behavior of application when there is a Network problem and the user is performing operations for data call. Users get proper error messages like “Network error. Please try again later.”
  • Stress Testing:  An important way of ensuring the stability of the app being developed. For this we tested the app by quickly tapping on multiple button/links/link images etc. By making such multiple requests at the same time, we tried to improve the app stability.
  • Testing with Different Network Types:  The app was tested on various network types including 2G, 3G and Wi-Fi.
  • Testing with Devices of Different Resolution: We tested the app on a variety of screen resolutions, ranging from 240×320 to 1280×800.  Due to availability of selected devices, the team tried to ensure that the app would work on different screen resolutions and mimic their behavior. For instance, a 10’’ tablet takes portrait orientation as well as landscape. Also the UI was different for tablets and devices.

If you have made it this far, you should take a minute to download the application on your Android smartphone or tablet. Let us know what you think with a rating in the Play Store or a comment in the comments section below!