The ViewHolder Pattern

As you develop your Android application, performance becomes more and more important. If your application appears slow, the user will get frustrated and not want to use it. One example of where this could happen is in the scrolling of a ListView. ListViews are a popular way to display information and can be done very poorly.

Each ListView has an adapter that is responsible for displaying the information in the list, and many times we’ll want to write a custom adapter to do something special. Within that adapter, the getView() method is responsible for figuring out how to display each cell in the list.  There are two main ways you’ll see developers implement this method–the right way and the wrong way.

The wrong way:

public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater mInflater = mContext.getLayoutInflater();
    View convertView = mInflater.inflate(R.layout.buddy_list_item, null);
    Buddy buddy = getItem(position);

    ((TextView) convertView.findViewById(R.id.buddy_full_name)).setText(buddy.getFullName());
    ((TextView) convertView.findViewById(R.id.buddy_username)).setText(data.getUsername());
    return convertView;
}

In this example, each time a cell needs to be created, the ListView will need to find the View and its components (see where findViewById() is called?). This means the code will scan over all the layout resources and find this View and get its components to then populate in the cell. This is very expensive, and could lead to poor performance.

The correct way:

public static class ViewHolder {
    TextView fullName;
    TextView username;
}

Now, we use a ViewHolder which will represent a cell in our ListView. The ViewHolder will be attached to the tag field of our View. This will make it much easier for the ListView to recall the correct View and components, rather than calling findViewById() many times. Let’s see how it’s used in the getView() method.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView==null) {
        holder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.list_item_buddy, null);
        holder.fullName = (TextView)convertView.findViewById(R.id.buddy_full_name);
        holder.username = (TextView)convertView.findViewById(R.id.buddy_username);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final Buddy buddy = buddies.get(position);
    holder.fullName.setText(buddy.getFullName());
    holder.username.setText(buddy.getUsername());
    return convertView;
}

Here, we only inflate a View from scratch if convertView is null. Otherwise we have a reference to the View through the convertView’s tag, and we don’t need to call findViewById at all! This leads to great performance and smoother scrolling in our list.

Hopefully it’s clear why the ViewHolder pattern is superior. There are some great Android docs that touch on this. If you need clarity or have questions or suggestions, be sure to comment below!

Happy coding!
Brandon from The Bunch

TinyPNG

panda
TinyPNG was used to compress this image and subsequently decrease this page’s load time.

TinyPNG is easily the coolest tool I’ve come across recently. I was looking for an easy way to compress images used on LunchBunch’s website to improve load times, and TinyPNG couldn’t have made it any easier. I’ve compressed PNGs and JPGs (it works with both) with average compression results between 40% and 80% depending on the source and original size. The website is very easy to use too–just upload your images and download a zipped file containing the compressed versions (or optionally save directly to Dropbox). And it works just as well on PNGs with transparency.

Compression is awesome, but what about the quality? PNGs are lossless, meaning that an image won’t change when compressed, but the quality of JPGs deteriorates as the file size shrinks. You don’t have to worry about image quality with TinyJPG–see for yourself at the bottom of TinyJPG’s homepage. The compressed version is barely a quarter of the size of the original, but I can’t tell the difference between the two images!

So after learning all of this, I was hooked. I was excited to use TinyPNG for everything, but what if I want to tinify my images programmatically? Lo and behold, the developer API! With libraries for Ruby, PHP, Node.js, Python, and Java, it is very easy to incorporate TinyPNG into any project. For example, my first attempt in Python was just a few lines:

import tinify
tinify.key = "<your-developer-api-key>"

def tiny(input_filepath, output_filepath):
    source = tinify.from_file(input_filepath)
    source.to_file(output_filepath)

And it just worked!

It seems easy to preserve metadata, integrate with Amazon S3, and even crop/resize before compressing (though I haven’t explored these features yet).

Every once in a while you stumble across a tool that’s exactly what you were looking for. For me, TinyPNG was that and more. If you have a website or use pictures in any way, this is a must-have tool for your project. There’s also a WordPress plugin that is super simple and highly-recommended for your blog.

How do you use TinyPNG in your projects? Let us know in the comments below!

Happy coding!
Ryan from The Bunch

JodaTime

Time throws a kink in programming sometimes.
Time throws a kink in programming sometimes.

Programmers are no stranger to obstacles, but some seem a lot more daunting than others. Time has been my Achilles heel from the beginning–getting time wrong is a major issue for the front end (and the back end too). If a user thinks their Invitation is set for 4:00PM, but they see 9:00PM on their phone, they’ll be wildly confused! So we as developers have to get this right.

In steps JodaTime, a library with the sole intent of making this struggle a little less of a nightmare.  It’s still no walk in the park, but it’s definitely an improvement. One of the biggest use cases for time is converting between time zones. For instance, you should store all times in your application in one time zone (with the understanding that you have users from different time zones), and then that time is converted to the user’s time zone on the front end.  UTC is the standard that is commonly used for storing timestamps on the back end.

To use JodaTime to convert from UTC to the user’s time, do the following:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZoneUTC();
DateTime dateTime = formatter.parseDateTime(someStringTime.withZone(DateTimeZone.getDefault();

Of course, there’s more than one way to skin a cat! Head over to JodaTime’s site, and figure out a way that works for you!

Happy coding!
Brandon from The Bunch

Development and Production Environments

When you’re working on an app that’s live, it’s a good idea to have a development version running that is completely separate from the production version. This way, when things go wrong (and they will), your users are less likely to be affected. Here are three things to consider when separating your production and development environments.

Data

This should go without saying, but the dummy data used in testing shouldn’t be be available in production and vice versa. It shouldn’t even be stored in the same databases. Confining user data to production keeps it safer, and keeping test data out of production makes your live databases cleaner.

Hardware

Keeping separate hardware is wise depending on the type of application you’re running, how many users you have, etc. It’s likely that the required load on the production server will be much higher than the server your team uses for development, so the hardware needs won’t be the same. By separating the hardware, you’re able to scale up and down independently and with minimal impact, and it also helps to reduce the impact of each environment on the other.

Security

Dev servers can have have different authorization permissions to make sure that the right people have access to your application until it’s secure and ready for public use. Security updates and other patches for your OS, libraries, etc. can be issued on your development server without affecting production. That way you can handle upgrade issues on dev and be more prepared when you need to update production.

Two environments is the minimum you should consider configuring for any application. Depending on the size of your team and the nature of the application you’re working on, it’s usually a good idea to have a staging environment which is treated as the most-recent stable development build which is next in line to be pushed into production. It’s also a good idea to have local environments for each developer to work individually without affecting the rest of the team. So the workflow looks like this:

  1. Developers work on their branches locally.
  2. When the local build is ready, it is pushed to dev for the rest of the team to use.
  3. When the dev build is stable, it is pushed to staging.
  4. Once approved by quality assurance and beta testers, the staged build is pushed to production.

This is a very high-level overview of multiple environments, and each project has different needs, so this is in no way a comprehensive writeup about how your pipeline should operate. However, if you’re getting started on a project, I hope this article has given you some ideas to consider.

What do your environments look like? Anything you would add to this post? Let me know in the comments below!

Happy coding!
Ryan from The Bunch

Logout Security

After building a login system, there are still a few considerations to take into account. Authorizing each endpoint is a good way to make sure that only logged-in users have access to the web app. Securing logout is also imperative, especially on shared computers.

When a user clicks the logout button, it’s common to redirect them to a publicly-accessible page. However, what happens when he or she (or the next person to use the computer) clicks the browser’s back button? Chances are that the browser has a locally-cached version of content that should no longer be available now that the user has logged out. Fixing this is pretty simple–just add the following headers to the response for each page with authorized data:

response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = 0

These headers (for HTTP 1.1, HTTP 1.0, and proxies, respectively) tell the browser (and any proxy) not to cache this response. And that’s it! Now if a user logs out then navigates through the browser history, any authorized page (i.e. any page that was sent with the headers above) will not be displayed. (Ideally, navigation to those pages when logged out would trigger a redirect to the login page.) And for most web applications, there shouldn’t be a noticeable performance hit–if there is, the time-loading tradeoff should be well worth the security benefit.

Have any other security tips for logging in or out of a web application? Let me know in the comments below!

Happy coding!
Ryan from The Bunch

Authorization Decorators

Last time I wrote about decorators, I explained their usefulness in rate limiting API endpoints. Today, I’m demonstrating another common use: authorization.

If you store the usernames of logged-in users in the session, your endpoint and decorator might look something like this:

@app.route("/get_secret", methods=["GET"])
@login_required
def secret_info():
    return "The truth is...I am Iron Man."

def login_required(func):
    def login_wrapper(*args, **kwargs):
        if not flask.session.get("username"):
            return "Unauthorized", 401
        return func(*args, **kwargs)
    return login_wrapper

That’s it! Just add @login_required to any endpoint at which you want to restrict access. It’s likely that you’ll want to do something more complex–maybe different users have different roles, or there are other attributes to check–but the concepts will be the same. There are good libraries for integrating HTTP Basic Authentication into your API which is another useful authentication method.

What authentication decorators do you use in your applications? Let me know in the comments below!

Happy coding!
Ryan from The Bunch

Salts and Hashes

For the past few years, “123456” and “password” have been the top two most-common online passwords. Storing passwords securely is very important for any application–not only to protect the users’ accounts from unauthorized access, but also to protect the passwords themselves. Because many people use the same passwords for multiple applications, a security breach on one site could have ramifications for other sites all over the internet. There are many methods used to protect passwords from getting into the wrong hands, and salts and hashes are two of them.

A hash function converts a user’s password to a string of fixed length from which the original text cannot be recovered. That is, if the password “qwerty” (surprise–another common password!) maps to “QmFzZTY0IGlzIG5vdCBhIGhhc2ggZnVuY3Rpb24hIQ==”, there is no way to recover “qwerty” given the hash function output. So by storing the hash instead of the original password, the security of the database is improved substantially, because even if this hash is compromised, whoever has it won’t be able to recover the original password.

Sounds good, right? Yes, but there’s still more to do. If an unauthorized person gets the hash, he or she can use our hash function on random strings and compare that output to this hash. By testing common passwords, there’s a good chance that the unauthorized individual will try “qwerty” and notice that the hashes match. (Note: It’s possible that two different inputs will map to the same hash, but this is very unlikely.) This is where salts come in handy. A salt is data that is added to the input text before it is hashed. So let’s say that the password is “qwerty” and the salt is “c2FsdA==”. Now, the hash function is run on “qwertyc2FsdA==”, which should have an output distinct from the the hash of “qwerty”. An unauthorized person needs to know the salt in order to test common passwords or use rainbow tables.

There are a plethora of hash functions available, but they are not all created equal. I feel that it’s important to note that Base64 is not a hash function. Contrary to hashes, any Base64-encoded string can be decoded to recover the original text. But there also are true hash functions that aren’t secure. Bcrypt is a good place to start.

Happy coding!
Ryan from The Bunch

HTTP Verbs

APIs often support different methods (HTTP verbs) that communicate to the client/server what kind of action is taken at that endpoint. The two most common methods are GET and POST. There are several others (PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT), but we’re going to focus on GET and POST today.

Endpoints that employ GET do exactly that–they get information from the server and return the results to the requester. Endpoints that use POST usually make changes to the backend in some way–inserting, updating, or deleting something in the database for example. GET is called an idempotent method because its effect on the backend is the same whether the endpoint is hit once or multiple times. This can be true for POST requests too (e.g. /logout where username=”broberts” can be called one time or 100 times, and broberts–and only broberts–will be logged out), but in general, POST is not an idempotent method. RESTful APIs are stateless, so if you use GET at one endpoint, you should get the same response if you hit that endpoint again with the same parameters.

It’s important to note that HTTP methods don’t have special properties–from a functionality standpoint, anything you can do with GET you can do with POST (and vice versa). But that doesn’t mean that you should. One of the reasons it’s good not to make all your endpoints use GET is link prefetching. Browsers might prefetch pages (any GET request) that it thinks a user will visit soon. If your logout endpoint is prefetched, then users’ browsers might be logging them out via link prefetching as soon as they log in!

For more information, W3Schools has some great documentation that provides a closer look at the differences between GET and POST.

Happy coding!
Ryan from The Bunch

Rate-Limiting Decorators

Decorators are great for APIs because they cleanly abstract shared functionality from different endpoints. Rate limiting is a great use case for decorators and should be incorporated into just about every API. Rate limiting ensures that there aren’t too many calls originating from the same user/IP address/etc. in a given timeframe. This can prevent the server or database from getting bogged down with spammy requests.

Let’s look at an example. Your application is a math API and has an endpoint /get_fibonacci for computing the nth element of the Fibonacci sequence. This is a computationally expensive operation, and you know that users don’t need to hit this endpoint more than a few times per day. That is, if a user is calling it multiple times in a short window, either there’s an error in the application that is causing that function to be called many times, or the user is abusing the API. Either way, the overloaded server is doing more work than is necessary, and we can prevent this with rate limiting.

To be safe, let’s allow each user call this endpoint 10 times every 5 minutes. If we only expect 2 or 3 calls every 24 hours, this should be plenty, and legitimate users won’t be locked out. If the application has a login system, you can limit based on username. Otherwise, IP address, user agent, or some other identifying data will work. You will need to store a dictionary that maps each user to the number of calls in the past 5 minutes. If you are looking for code to use in your project, you might want to check out a complete example (← code snippet uses Flask).

For an easier code example, let’s say we want to limit API calls by time of day instead of rate–calls are allowed only between midnight and noon. (There’s a use case for that, right?…🙂) This would be our code:

@app.route("/get_fibonacci", methods=["GET"])
@ratelimit
def fibonacci():
    n = int(flask.request.args["n"])
    a = 0
    b = 1
    while b < n:
        a = b
        b = a + b
    return str(b)

def ratelimit(func):
    def ratelimit_wrapper(*args, **kwargs):
        if datetime.datetime.utcnow().time().hour > 12:
            return "Sorry, please try again tomorrow in the AM!"
        return func(*args, **kwargs)
    return ratelimit_wrapper

Then navigate to {host}/get_fibonacci?n=5 to see it in action.

This means that before the given Fibonacci number is computed, the decorator checks to see if the current time is before or after noon. If it’s after noon, the error message is returned to the user. Otherwise, the fibonacci() function runs and returns the result to the requester.

Here’s a line-by-line description of everything that’s going on:

  • 1. This function can be accessed via GET at {host/application_root}/get_fibonacci
  • 2. Attaches the ratelimit decorator to this endpoint (more accurately, it wraps this function with the ratelimit function)
  • 3. Function definition
  • 4. Extract GET parameter from the URL
  • 5/6. Initialize first two elements of the Fibonacci sequence
  • 7. Repeat until we find the nth element
  • 8/9. Get the next element in the sequence
  • 10. Return the nth element (View function expects a string response)
  • 12. Decorator definition
  • 13. Wrapper function that surrounds the decorator–accepts any arguments
  • 14. Check the time in case it’s after noon
  • 15. This is returned to the requester without ever calling fibonacci() if it’s after noon
  • 16. It’s before noon, so return the output of the original function
  • 17. Return this decorator wrapper

Decorators can be confusing at first, but they’re powerful and great for writing simple, clean code. If you have any questions, please let me know in the comments below!

Happy coding!
Ryan from The Bunch

Extending Application

As you develop your Android application, you may find it necessary for certain libraries or settings to be initialized on app startup, rather than during normal application use. This can be done simply by extending the Application class. Simply create a class and have it extend Application, and in the onCreate() method, just initialize the library:

@Override
    public void onCreate() {
        super.onCreate();
        /* Initialization of some cool library */
        SomeLibrary.init();
    }

Now, after we’ve created this class, we need to tell our application to use it! That’s simple too. Just put

android:name=".mypackagename.MyClassThatExtendsApplication"

inside your application tag in your AndroidManifest.xml. This will tell your application to use the class you’ve defined as your Application class, and the OnCreate() method will be run, making sure your app is configured correctly. Another great use case for this is setting up a crash report library. The library will want to start listening for crashes immediately, so the best place to set that up is in the Application class.

Happy coding!
Brandon from The Bunch