Things you need to know before publishing your first Android app

So you’ve been working hard on your first Android app and you’re satisfied with the result so far. There’s always room for more improvement, of course, but you’ve decided that this is ‘good enough’ to ship. Good! No one does something perfectly the first time (or ever, really) so kudos to you for making the decision.

So anyway you’ve finally decided to release your creation to the public. You feel ready to do it, but you’re not sure what you should know beforehand. This is the first time you’re actually publishing an Android app to the Play Store and you don’t want to screw up. What do you need to know?

In most cases, it’s a good idea not to think too much and just do it. I’m sure you believe, as software developers, in the power of learning by doing. That’s how we all learn, after all.

But in this case, there are a few things that you should know before publishing your Android app which can cost you dearly if you ignore them.

Keystores and app signing

All Android APKs need to be digitally signed with a certificate before you can install them. This is done to ensure that you’re the sole legitimate owner of your app as well as any consequent updates to the app, so no one else can distribute apps under your name. Only you hold the private key to the certificate that you use to sign your APK, so if an attacker tries to make a counterfeit app using the same package name and tries installing it onto an Android device with your app already installed, the Android system will block the install because the attacker, due to lack of access to your private key, signed the APK with a different key, and the Android system can tell this.

Oops! APK signature changed.

While developing your app, every time your apps needs to get deployed on an Android device or emulator, Android Studio signs your APK with a debug key. (You can find your debug key in the .android folder inside your home folder.) While this works great for development because you don’t have to manually sign APKs for every deployment, it doesn’t work when you need to finally publish your app.

This is where the release key is needed. The release key is basically a key that you generate and use to sign apps with. After signing your APK with this key, you can proceed to uploading your APK to your Google Developer’s account.

Note that you need to keep this key private – anyone in possession of your key can sign APKs with it.

Google Play App Signing

When you upload your APK in your Google Play Console for the first time in your app, you have the option to enable Google Play App Signing. What this does is, it takes the responsibility of keeping the signing key safe off of your shoulders and onto their own.

How it basically works is this: with Google Play App Signing enabled, when you sign your APK with your own secret key and then upload it and publish your app, Google removes your signature and replaces it with their own. You can verify this by checking the public key of the APK you generated versus the APK you get after you download the app from Play Store.

The signature of the APK generated with Android Studio.
The signature of the APK that your users receive from Play Store.

See the difference? Here, my original key (first image) acts not as the signing key of the app, but rather the upload key. This key is disposable – you can afford to lose it as you can request a new one with Google and continue pushing updates to your app with your new upload key. This is the advantage of using Google Play App Signing. The key generated by Google (second image) acts as the real signing key, and this one cannot change, but it doesn’t matter too much because it’s Google’s responsibility to keep it safe.

If you want a longer expiration date, you should choose to opt out of Google Play App Signing when you first upload your app

One interesting thing to note here is how the expiration time reduced from my initially set ~100 years to 30 years for the new signing key. I’m not sure if this behaviour is documented anywhere, but if you want a longer expiration date, you should choose to opt out of Google Play App Signing when you first upload your app, then turn it on again if you want it. This is a bit more cumbersome since you’ll need to upload your actual signing key to Google’s servers, and you’ll also need to generate a new upload key to use in its place. But the good thing is, your apps will be signed with the key that you choose, with the expiration date that you set.

Conclusion

Whatever your decision, just remember that whether you choose to keep your signing key yourself or you leave it to Google, you must not lose the signing key. You cannot publish updates to your app under the same package name if you do.

You also need to keep your signing key secure. If anyone else gets hold of it, they could distribute malware under your name.

Also, be aware of the expiration date that Google imposes on your APK on behalf of you. If you want to configure it yourself, be sure to opt out the first time you upload your APK, then opt in later if you wish. You cannot publish updates to your app beyond the expiration date.

There are other things to consider for sure. But these are the most basic things that apply to pretty much any Android app, no matter how small or large or what services it makes use of.

Why you should stop using ListView

If you’ve been an Android developer for any length of time, you’re probably familiar with ListView. It’s a ViewGroup that displays a scrollable vertical list of views. It’s simple enough. You’ve probably also heard of RecyclerView, ListView’s newer, cooler cousin which might be good, but you probably don’t need to use it. Right?

I’ll get straight to the point: there is no real reason to continue using ListViews. This is especially true if you’re working on a new UI or app from scratch, because RecyclerViews are so much better. You could potentially save hours of time in the future by making this one choice – I know because I learned this the hard way.

But RecyclerView is too complex!

I understand why you might feel that way. RecyclerView is certainly more powerful and more flexible than ListView. It allows for broader functionality and actually performs better without additional boilerplate code (I’ll get to that in a bit). But it isn’t really any more complex. If you just want a vertical list, RecyclerView can certainly give you one. Consider the following code for a ListView adapter that displays a title and a description for each item:

public class MyListViewAdapter extends BaseAdapter {

    private Context mContext;
    private List<Pair<String, String>> mItems;

    public MyListViewAdapter(Context context, List<Pair<String, String>> items) {
        mContext = context;
        mItems = items;
    }

    @Override
    public int getCount() {
        return mItems.size();
    }

    @Override
    public Pair<String, String> getItem(int position) {
        return mItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup container) {
        MyViewHolder holder;

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater)
                    mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.item_list, container, false);
            holder = new MyViewHolder();
            holder.titleTextView = convertView.findViewById(R.id.text_title);
            holder.descriptionTextView = convertView.findViewById(R.id.text_description);
        } else {
            holder = (MyViewHolder) convertView.getTag();
        }

        holder.titleTextView.setText(getItem(position).first);
        holder.descriptionTextView.setText(getItem(position).second);

        return convertView;
    }

    private static class MyViewHolder {
        private TextView titleTextView;
        private TextView descriptionTextView;
    }
}

Here’s code that does the same thing using a RecyclerView adapter:

public class MyRecyclerViewAdapter
        extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
    private Context mContext;
    private List<Pair<String, String>> mItems;

    public MyRecyclerViewAdapter(Context context, List<Pair<String, String>> items) {
        mContext = context;
        mItems = items;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(mContext)
                .inflate(R.layout.item_list, parent, false));
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.titleTextView.setText(getItem(position).first);
        holder.descriptionTextView.setText(getItem(position).second);
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    public Pair<String, String> getItem(int position) {
        return mItems.get(position);
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView titleTextView;
        private TextView descriptionTextView;

        public MyViewHolder(View itemView) {
            super(itemView);
            titleTextView = itemView.findViewById(R.id.text_title);
            descriptionTextView = itemView.findViewById(R.id.text_description);
        }
    }
}

As you can see, RecyclerView is using less code than ListView in this example. You also probably noticed that the ListView example above is using a common ListView pattern called the “ViewHolder pattern”. It is basically a way of making your ListView render views more efficiently by reusing previously rendered views using a class called the ViewHolder. This makes sure that your views aren’t rendered from scratch every time the user scrolls to them.

Performance may not seem like a priority in this example, so using ViewHolder could seem unnecessary, but consider what would happen if your adapter fetched some data over the internet, let’s say an image, and rendered it. Every time your user would scroll up or down a view that had already been viewed, it would fetch the data and render it again. Not only is this a terrible waste of the user’s mobile network (which is, or should be, assumed to be limited like most things in mobile devices), but it also makes for bad UX in general and goes against user expectations.

My point is, as a rule of thumb, if you’re using a ListView, chances are you are using a ViewHolder to recycle views and if you’re not, you probably should. Even if your adapter does not need internet access, rendering views, especially complex ones, can be an expensive task.

This is where RecyclerView shines. If you look at the RecyclerView example above, you can probably tell that the RecyclerView uses the ViewHolder pattern as well, but it does so automagically. You don’t need to check any views for null, all you need to do is create a ViewHolder class that extends RecyclerView.ViewHolder, declare and assign references to views in the ViewHolder (which makes more sense than the ListView approach), return a ViewHolder from the onCreateViewHolder method and modify view for each item as needed in the onBindViewHolder method. RecyclerView handles the recycling for you (hence the name). It’s a much cleaner, nicer approach compared with what you normally do with a ListView.

You can use RecyclerView for other things too

RecyclerView is more general-purpose than ListView. This means that a RecyclerView can do everything a ListView can do and more, but not vice versa. For example, a ListView can only be used for vertical lists, but RecyclerView supports horizontal lists as well. You can even create a grid using GridLayoutManager with RecyclerView. And in all cases, the recycling of views is handled automatically for you.

Automatic recycling = less headache

If you’re planning on making a complex list with input fields for each view with changing data depending on user interaction, you’d be better off using RecyclerView. With increasing code complexity, the code that would handle recycling in a ListView also gets more complex. Having one less thing to worry about can be save you hours of time and allow you to focus on what your main task is. I know this because I’ve experienced the pain of trying to fix a problem in ListView that just vanished when I switched over to RecyclerView. I don’t know what exactly the problem was because I never needed to figure it out, but I know it had to do with the way I was recycling views in my ListView manually.

So even if you’re already using ListView and are comfortable with it, you might still want to consider switching to RecyclerView if the code is likely to undergo any development in the future.

Conclusion

RecyclerView > ListView

RecyclerView offers broader functionality and less boilerplate than ListView, and it’s not more complex. In fact, the reduced boilerplate makes it arguably less complex.

I’m actually surprised ListView still hasn’t been deprecated, but I suspect it will be eventually.

How to reduce your Android app size

The size of your Android app is an important factor to consider. Users are more likely to download your app if it’s relatively small in size, especially if they’re on a slow 2G or 3G connection. Here are a few things you can do to reduce your Android app size.

Analyze APK

Android Studio has a neat little feature called “Analyze APK” that lets you, well, analyze an APK file. It shows you useful information like what the APK’s download size would be after it’s published to the Play Store, which parts of your app are taking up the most space, and so on.

Click on “Build” menu in the menu bar at the top, then select “Analyze APK…”.

Screenshot of Android Studio showing Analyze APK in dropdown under

In the dialog box that appears, choose the path to your generated APK (preferably the release version, because that’s really what you’re interested in optimizing). You should now see the following window.

Analyze APK window

Here, you can see which parts of your app are taking up the most space. You can stop reading right here if this is what you were after, but if you’re already done this and are looking for more ways to optimize app size, read on.

Evaluate your dependencies

Dependencies, dependencies everywhere

If you haven’t looked at your app’s Gradle build file in a while, you might want to do just that. It’s all too easy to add dependency upon dependency as you come across new libraries your app needs, and then stop using a library but forget to remove the dependency declaration. Removing unneeded Gradle dependencies can then be a great way to reduce your app size. And even if all your dependencies are useful, it’s worth considering which ones you really need if your APK is still too large.

Are your resource files too large?

Resource files are another great place to look when trying to shrink your APK. Find any large images or other media files that are too large and consider compressing them. There are many free image compression services online you can use if you can’t/don’t want to compress them yourself. For PNGs, you can use tinypng.com. It compresses PNG files losslessly, so the quality of the image is preserved despite the drop in size.

This list isn’t exhaustive. I’m pretty sure there are many, many other ways to reduce app size, but these helped me tremendously – I was able to reduce an app from 6 MB down to around 3 MB – that’s half the original size! Now that was probably because of the existing hot mess of large, unused dependencies, so depending on your situation everything I described here may or may not work for you. But I think it’s a good place to start.

Have your own way to optimize app size? Think I got something wrong? Let me know in the comments below!