Android Developer

Los Angeles Freelance Developer

Android Developer header image 1

Introducing EssentialsLoader

May 6th, 2013 · Android, EssentialsLoader, OOP

Allow me to introduce EssentialsLoader. EssentialsLoader is my image loading (lazy loading) system that I’ve been using for sometime now. It’s part of the Essentials tools (along with EssentialsLogger) that I’ve created and decided to release publicly. So why did I create my own image loading system when there are others out there such as Loading Large Bitmaps Efficiently from Google? EssentialsLoader address a couple of important issues which most other systems were not handling to my liking.

First, EssentialsLoader decouples the view from the loading process. What does this mean? Take for instance Google’s lib that I linked to above. You are required to reference an ImageView to load a bitmap. Now that’s just down right silly. So to use their lib I’m forced to use an ImageView and I have no control over how or where the loaded image will go! I can’t change the drawable shape; I can’t set it to be a background; I can’t set the scale type on load; and I don’t get a Callback for when it has loaded. But back to my original point. A loading system should not make the assumption of how the loaded image will be used. EssentialsLoader decouples this process and you are free to use the loaded bitmap however you’d like.

Secondly, most loading system do not expose the cache. They are often created internally and you have no way to access them. What if you wanted to share the disk cache across loaders but not the memory cache or vise versa? Or what if you wanted a custom type of cache allowing you to cache and/or reject Bitmaps at your whim? EssentialsLoader allows you to do this by passing in the cache of your choosing in the constructor.

The lack of a good and architecturally flexible system has frustrated me for sometime now (along with the lack of a HorizontalListView….come on guys…). I’m hoping EssentailsLoader can start filling in this void. This post was more of an introduction and I don’t have any follow up post in mind to elaborate on it. So go check out the samples and if there’s an architectural point you’d like for me to address in a blog post feel free to send me a message or leave a comment.

Happy loading!

→ 4 CommentsTags:······

The Cost of Development

February 2nd, 2013 · Android, Freelance

In previous years I was part owner in a small web business. The business was based around the idea of dynamically creating Flash websites through a real-time GUI that was easy enough to use that even Grandpa Bert could make, create, and design his own website in 30 minutes. We had a great front end team with highly skilled individuals. Unfortunately, a business decision was made to out source the backend to a team who charged a mere fraction of the cost of an in-house team and this was the decision that killed our business. How so?

It’s not a bad thing to want a deal. We buy stuff on sale all the time (such as my brand new 55″ 3D TV at a huge discount which is great for Nintendo Land). So what is the difference between developers and the rates they charge? Why might my hourly rate be more than developer “Guy Foo”? And even though it might be, how will the client still save money in the end?

I recently joined a project about 2 months into it. The application was suffering from lag when scrolling a ListView component. The amount of lag was more than just noticeable but significantly interrupted the usability of the application. At this point there had been 2 developers, 1 project manager, and 2 quality assurance people working for 2 weeks on this issue among a slew of others. The following is comparative analysis report I wrote for the client detailing the changes in performance from my refactoring. Let’s begin:

A Quantitative Analysis of a Refactored Project

While I could see the lag, the first thing I did was confirm my suspicions that the application was taking too long to render a frame.  To measure the drawing I profiled scrolling the ListView by doing a system dump of the “gfxinfo” and mapped it to a bar graph. The bars in the diagram below represent how long each frame took to draw. Anything over 16 milliseconds is lag and becomes noticeable to the user.

There are two spikes in the graphic that occur when an image is added to the renderers in the ListView. A user sees this as jitter. Below is another graph but instead of profiling the scrolling on a ListView it profiles the opening layout of the application.

Notice the y-axis is out of 100 milliseconds. The first quarter of the graph is all above the 16-millisecond threshold as well as the part. 80 milliseconds of lag is very noticeable to the user.

The graph below is from after the refactoring. Notice the y-axis is out of 12 milliseconds. When the ListView is now scrolled there is no lag in drawing as it is under the 16-millisecond threshold.

The next graph is of the startup time. As before, each bar represents a single frame of execution. After the refactoring only one or two frames are above the 16-millisecond threshold during the opening of the application. This is a significant improvement. Had time permitted, the xml layouts could have been refactored further reduce these times.

Must Go Deeper

While measuring how long each frame takes to render gives a very good idea what is going on it doesn’t tell the full story. There could be lag between the frames which would cause rendering to be skipped. I checked this by running a “systrace” on the application. The below graph is from before the refactoring and was profiled while scrolling the ListView.

The green represents how long Android spent going through all the UI elements on the screen (traversing the hierarchy) and the blue represents how long Android spent measuring the layouts. The small bars of purple are how long the drawing took. Notice how large the first 4 blocks are. These large blocks are measured around 183 milliseconds. This is 183 milliseconds between drawing frames which is 11 drawing cycles skipped. The UI lagged for 11 frames before the next update was made. You can see that below the large blocks there is no purple which means the draw was skipped.

Below is the graph after the refactoring. Both graphs have the same x-axis time scale of starting at 1 second and ending at 2 seconds (means the widths of the gree and blue bars can be compared). Notice the frames are much smaller. Here the layout and traverse take 5.5 milliseconds which is below the 16-millisecond threshold and a draw occurs.

Draw All The Things!

Drawing is an expensive operation. Android can draw the entire screen about 1.5 times before it lags. The below graphs are heat maps of how many layers Android had to draw to render the UI. The coloring means:

  • No Color – no overdraw occurred
  • Blue – 1 overdraw occurred
  • Green – 2 overdraws
  • Red – 3 overdraws
  • Dark Red – 4 or more overdraws

An efficient application will be in the blue with a little bit of green and reds. A little red/dark red is ok.

Below is the Overdraw map before the refactoring. Notice it is very red.

And the below image is from the refactoring.

It’s now mostly blue. The ListView is 2 steps of improvement, down from red and green to blue.

Moar Power

The graphs below show the CPU consumption from scrolling the ListView before and after refactoring, respectively. The green bar represents the time the CPU spent in processing the application while the red deals with the Linux kernel. The refactored version consumes about a third of the CPU from before.

Nesting Is For the Birds

While there are still more ways to profile an application the final test I did was to look at the view hierarchy. The below two images show the hierarchy before and after refactoring. Notice it’s nearly the same. While the hierarchy is rather deep, due to time and money constraints I only refactored small pieces of the xml layout files. While not ideal it’s okay as the application performs well despite the deep hierarchy.

Before:

After:

There Are Other Things

There were other things I could have done to gain even more performance such as limiting the “requestLayout”s of the ImageViews in the ListView. However, without refactoring the xml layouts most of the other performance increases couldn’t have been done. But even without this, the application is running great and each frame renders under the 16-millisecond threshold.

It’s All About the $$$

To get these performance increases, the changes I made in refactoring included:

  • The splash page
  • The interstitial ads
  • The banner ads
  • The Slide-to-Open Pull Menu
  • The navigation
  • The main content page and it’s 3 subpages
  • And finally a popup dialog.

In addition to refactoring the application for performance increases, I was able to properly encapsulate these areas. All of changes took 19 hours of my time.

There are hidden cost of development.

That was the end of the report. As I mentioned above, before I refactored there were 2 developers, 1 project manager, and 2 QA people working on and trying to fix these issues for 2 full weeks. Had the decision been made to do this from the start the difference would have been 381 saved man-hours and a better application from the initial launch. Additionally, this was just 1 area of the application. There were other areas where QA was taking longer than it should have. There are hidden cost of development. Going back to my original story about my web business, after 18 months of working with the outsourcing team and it being an utter failure, the team was completely fired. We decided to throw away the entire code base and 18 months of work by 5 people. Me and the other front end developer rewrote the entire backend in 4 months and it was great. The company lost 18 months of salaries, plus an additional 4 months to rewrite the backend, plus 2 years of lost business revenue, among other things. In the end, it was just too much for the company to survive.

I’m a firmer believer that when you hire, hire good and hire well. You’ll be more likely to end up with a superior product that’s extensible and flexible to change and will out perform what would have been the alternative. And in the end it will cost less to develop.

→ 3 CommentsTags:···

ImageViews and Stars and Other Unique Shapes

December 30th, 2012 · Android, Drawables

Romain Guy is doing a series on Android performance and drawing. In his first post, he demonstrates an ImageView with rounded corners by using a custom Drawable. I wanted to learn more about drawing and paints and shaders so I did some of my own experiments drawing star shapes using pictures of kittens. (Unicorns will be next…) You can grab the full sources here.

There are a couple of important objects used in drawing:

Canvas
The Canvas object is passed to us and this is where we make our drawing commands. You can think of this as like the canvas to an oil painting.

Paint
The Paint object is kind of like it sounds. It supplies the source color for the thing drawn. It may be a single color or in the case of bitmaps we set a BitmapShader which Paint will use as its source.

Path/Rect/etc….
These objects define the shape of what is drawn to the canvas. In my stars sample, I used a Path object to draw the 5 points of a star connected by lines.  And if you looked as Romain Guy’s example of rounded corners (included in my source code as RoundedCornersBitmapDrawable) he uses a Rect object.

The Drawing
To draw you just need 3 things: a canvas, a shape, a color. It’s actually quite simple. In StarsBitmapDrawable it’s this:

@Override
public void draw(Canvas canvas) {
   canvas.drawPath(path, paint);
}

Note: When you make a custom drawable, do override the methods getIntrinsicWidth and getIntrinsicHeight. The defaults return -1 and is generally not what you want.

A Little Trig
I’m not going to go too heavily into the math used to draw a star. The basic idea is to find the coordinates of each point of the star and connect them with lines. The Path object will fill the space. The image below shows how with just a little trigonometry and algebra I was able to come up with the points.

Which gives us code like this:

// truncated code...full code in sources
public class StarBitmapDrawable extends Drawable {
 
public StarBitmapDrawable(Bitmap bitmap) {
    super();
    this.bitmap = bitmap;
    paint = new Paint();
    paint.setAntiAlias(true);
    shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    paint.setShader(shader);
    path = new Path();
//        paint.setStyle(Paint.Style.STROKE);
}
 
@Override
protected void onBoundsChange(Rect bounds) {
    super.onBoundsChange(bounds);
 
    int minDim = Math.min(bounds.width() - paddingLeft - paddingRight,
    bounds.height() - paddingTop - paddingBottom);
 
// b = |
// a = _
// hyp = \
 
// bigHypot = height / cos(18)
    double bigHypot = (minDim / Math.cos(Math.toRadians(STAR_ANGLE_HALF)));
    double bigB = minDim;
    double bigA = Math.tan(Math.toRadians(18)) * bigB;
 
// lengths of the little triangles.
// littleC = littleC + littleC + littleA + littleA
// cos(72)*C = A
    double littleHypot = bigHypot / (2 + Math.cos(Math.toRadians(STAR_OPP_ANGLE)) + Math.cos(Math.toRadians(STAR_OPP_ANGLE)));
    double littleA = Math.cos(Math.toRadians(STAR_OPP_ANGLE)) * littleHypot;
    double littleB = Math.sin(Math.toRadians(STAR_OPP_ANGLE)) * littleHypot;
 
    int topXPoint = (bounds.width() - paddingLeft - paddingRight)/2;
    int topYPoint = paddingTop;
 
// start at the top point
    path.moveTo(topXPoint, topYPoint);
 
// top to bottom right point
    path.lineTo((int)(topXPoint + bigA), (int)(topYPoint + bigB));
 
// bottom right to middle left point
    path.lineTo((int)(topXPoint - littleA - littleB), (int)(topYPoint + littleB));
 
// middle left to middle right point
    path.lineTo((int)(topXPoint + littleA + littleB), (int)(topYPoint + littleB));
 
//        // middle right to bottom left point
    path.lineTo((int)(topXPoint - bigA), (int)(topYPoint + bigB));
 
//        // bottom left to top point
    path.lineTo(topXPoint, topYPoint);
    path.close();
}
 
@Override
public void draw(Canvas canvas) {
    canvas.drawPath(path, paint);
}
// truncated....more code in sources

→ 5 CommentsTags:···

Android Architecture: Structuring Network Calls, Part 3

October 7th, 2012 · Android, OOP

So far we’ve talked about some theory and OOP design principles and making our request asynchronous. In this post we’re going to discuss what was going on inside of the AsyncTask to make the network request and parse the data. Much like most of my posts, I won’t be discussing how to make a network request or how to parse xml or json. Instead, we’ll keep it broader and continue to talk about the architecture. [Read more →]

→ 8 CommentsTags:·············

Android Architecture: Structuring Network Calls, Part 2

September 30th, 2012 · Android, OOP

What is the Command Pattern? Even if you don’t know what it is you’ve most likely implemented it before. It’s a pretty simple concept: you encapsulate a behavior that can be executed at a later time. Does that ring a bell? In Android, there are two very common types of command objects that are used: Runnable and AsynTask. Think about it for a moment. In a Runnable, you put all your fancy code in the run method, and then pass that object to a client. Let’s check it out briefly: [Read more →]

→ 8 CommentsTags:·········