Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Android Studio 3.0 - Impacts and Possibilities

4.77/5 (12 votes)
25 Nov 2017CPOL12 min read 24.7K  
An overview of some of the new features in Android Studio 3.0

Introduction

Android Studio 3.0 is released. Finally. I was waiting months for it. While for many developers, this is "just the next version and whoow we can use lambdas", there are some interesting things available now which we can use.

None of them is entirely new, and there are some you might have never touched before, but maybe this article can motivate you to try something new.

This article does in no way (not even close) try to show you "all new features" or give you a complete what's-new-list. It's a list of things that caught my attention during the first week of working with the release version 3.0.

We will take a look at these topics during the article:

  • Bugs in Android Studio/Gradle in the current version
  • New Editor features and live templates
  • A short look at some Java8 features (there are already plenty articles on the web for this topic, I do not want to repeat them all)
  • What's new with the emulator
  • UPDATE What's new in build.gradle - the allmighty "implementation" and "api"

Discovered Bugs

Every new release has some bugs. Many of them are not recognized by the majority of users, even less are encountered by a single person.

Build System

I discovered a bug in the gradle build tools 3.0.0 while working on my libraries and I show it here because you will see this bug happen when you work with .aar libraries.

The bug is filed with Google and they already reported it as "fixed" with build tools 3.0.1. So with the next Android Studio patch, we can expect that it will no longer happen.

https://issuetracker.google.com/issues/68741204 The bug is, that gradle incorrectly reports files/folders attached to the build as "modified" and fails. So, if you encounter a build error because of a modified "layout-v16" file, even if you have minApi > 16, it's exactly this bug. Fix is on the way.

Until then, if you encounter this behavior in Android Studio 3.0, you need to do a Rebuild of the entire project. My experience showed that you need to rebuild everything every time you changed XML files (resources, layouts, themes, etc.). Java-only changes do not cause that bug to appear.

UPDATE 2017-11-26: Android Studio 3.0.1 patch is here. You can update your project build.gradle to

classpath 'com.android.tools.build:gradle:3.0.1'

now. The bug fix had its rollout and I can confirm, the described behavior really no longer happens.

Find Window

Another bug is with the Find-Window, where it can happen, that a deleted line ends up with wrong "INVALID" markers on your search results. It's filed here and still in investigation/reproduction state: https://issuetracker.google.com/issues/68806074. You can find a short screen-record-video in this bug to see what happens. If you encounter this behavior too, please star the issue.

Build Tools Version is Set to 26

A bug filed by another user which I second, is, that you are currently required to have build tools 26 installed, even if you converted all your projects already to 27. The bug happens when you create a new Project. Gradle then assumes the build tools 26, even if the new definition says "You no longer need to specify the build tools version. Gradle will default to latest installed."

While the default is correct, is does not apply to a new project at the time of writing this article. So keep in mind, that you do not uninstall v26 for now - https://issuetracker.google.com/issues/68301941.

Editor Features and Live Templates

Do you know and use the #region from C#? It's a nice feature to collapse code regions that greatly helps you keeping an overview of larger code files and it also is a great help for structuring "logical blocks" in your classes.

Android Studio (intelliJ) has the same thing. It's not new in 3.0, but the "Structure" code view of Android Studio now supports it, which is a great addition for me.

The syntax in Visual Studio is:

Java
#region My foldable section
public void SomeMethod()
{
//...
}
#endregion

In Android Studio, it looks like this:

Java
// <editor-fold desc="Properties">
public void someMethod { 
} 
// </editor-fold>

We can clearly see that Visual Studio's way is by far more convenient. "#region" is typed very quickly and does not really interrupt your coding flow, while typing such a Xml-Tag with a desc property is not so easy.

I think this is one of the main reasons why this feature is barely used by Android Developers. To help with that, I will create a short live template here with you, so you can utilize "regions" in Android Studio as easy as you do it in Visual Studio.

The effect is the same in both IDEs: You get a small (+) icon on the left border of the code view which allows you to collapse/expand this region. So you can easily hide some code from viewing.

New in Android Studio 3 is, that the "structure" window now fully supports those editor-fold regions and this increases the structure view's read- and usability a lot!

I personally use regions/folds very much, in my classes there is not a single line of code and not a single method not associated/put into such a region. This is true for all my C# programs as well as for my Android Apps.

I would like, if I may, to recommend you, that you give the "Structure" view a chance. Open it, re-arrange it to the right side of Android Studio, so you have your project view on the left and the structure view on the right while coding. It will increase your navigation speed. You can save your Window layout "as default" in the Window menu (first menu item in there), so you don't have to re-arrange your windows in every session.

Take a look at this screenshot from a code view with editor-folds and the corresponding structure view. There is only a small list of regions I need to read/scan with my eyes before I find the section where a method is located, instead of reading through dozens of method names and scrolling through an almost-endless list.

Image 1

Creating a Live Template

If you never created a live template so far: Live templates are the same as "code snippets" in Visual Studio. Android Studio has, in my opinion, by far a better approach to create those templates. I personally do not like the snippet syntax of Visual Studio very much and the support for editing/creating new snippets is... not there in VS.

To create a new live template in Android Studio, press Alt+Ctrl+S or open File-->Settings. You can now either navigate to the "Live Templates" section or simply type "live" in the search box at the top of the window. You then see this:

Image 2

Tip: Create your own Template Group for live templates, so you have all your custom templates together in a single place. To do this, click the green + at the right border and create a Template Group, like I did with the "_Mike_" section shown in the screenshot.

Once you have your group, click the green + again and create a new "Live template". You see this afterwards:

Image 3

  1. The "Abbreviation" is what you will later have to type in the code editor to launch your template. Choose something short, that is in context with the template and that you can remember. In my case, this was "ef" for "editor fold". You can later launch this template by typing ef + Tab key to insert it.
  2. This is just a short info message that will appear in IntelliSense. You see a screenshot below when I demonstrate the template.
  3. This is finally the code for your template. The syntax here is very easy: WYSIWYG. Type exactly what you want to see in the code window! Every term that is enclosed by $dollar_characters$ is considered a variable and be edited (and receive a default value) when you press the Edit variables button. When you launch the template, Android Studio will stop at the first of those variables and will allow you to enter a value there. Step through multiple variables with the tab key.

    Enter this in the Template text text box:

    Java
    // <editor-fold desc="$section$">
    // </editor-fold>
  4. This is the most important part. You have to define the scope, where this template can be launched. For this specific one, it's "declaration" as we want it to be available whenever Java would allow us to declare something. A member, a method, ... This is the point where we also want to have regions to group code elements together.

    Image 4

Apply your changes and close the settings window.

Using the Template

Now open a code file and start typing "ef" and see what intelliSense offers you:

Image 5

Great, isn't it? With only 2 characters, you entered that complex XML tag (complex in terms of "try to type it by hand").

As you can see in one of the screenshots above, I created many of those templates and they really can speed you up!

Live templates are nothing new, and neither is the editor-fold. But with the new structure view now showing those collapsed regions, it's worth being mentioned.

Java 8

Android Studio now supports Java 8 features. Well, Android Studio 2.3 already supported that if you enabled the Jack&Jil tool chain. This tool chain has been deprecated and it had a big flaw: Library projects could not be compiled with Jack. Which let us devs end up with "stick a bit longer with Java7" or use third party tools like RetroLambda. But we had no "real" way to use all that cool stuff.

With Studio 3, the waiting is over. Java 8 is now enabled and Jack is gone. You can easily find tons of articles about Java8 in Android. A good overview is here at https://developer.android.com/studio/write/java8-support.html.

The Biggest Impact

There are many good things in Java 8 but the one I consider as the most visible impact is the function references.

Gone are the days of:

Java
view.setOnClickListener(new View.OnClickistener() {
    @Override
    public void onClick(View v) {
        // doSomething
    }
});

This was something that I never liked very much. I always just wanted to call a method. Java does not know an event-syntax like C# does, and I do not want to say "C# is better here". I really like that callback-approach. But the syntax for that was... meh. On the other hand, to do "new" on an interface is something really cool! So this medal has two sides, as always.

Now, with lambda, the above code could be changed to:

Java
view.setOnClickListener( (v) -> {
    // doSomething
});

which is shorter. But with a function reference, we can finally get there, where I want it to be:

Java
view.setOnClickListener(this::onClick);

private void onClick(View view) {
    // doSomething
}

So what's the difference here?

First, the syntax. The double colon reminds a bit of C++ (nothing evil, don't get me wrong, just mentioning it). But we get one real advantage out of that:

If we do not make the onClick method private, but public, an inheritor can simply @Override the click listener method! It was not possible to override an inline-declared new View.OnClickListener(...). But now we can!

I think, this is the point, where the most visible impact will happen. If you decide to work through your libraries and update your source code to this new possibilities (like I did), you will hopefully end up with a much cleaner, easier to read and more understandable code.

Emulator

There is a very very nice new feature included with the Android emulator. Play Store access! Yes, you read right. AVD now has full access to the play store out of the box. Just create your emulator with a "play store" image and not with a "Google APIs" image (the new type of images is offered in the SDK Manager and when you create a new AVD).

Image 6

After you have booted that emulator, you connect your Google account the same way as you would with a physical device! I used my developer Google account, and everything is working normal. Gmail, Calendar, all the cloud stuff is available in the AVD. And of course, all the play store apps. :)

Yes, even games. Try it out - cool new thing!

What's New in build.gradle

(Update 2017-11-15)

There is another change that should be mentioned: the command compile(...) is deprecated now in build.gradle. You get a warning that says "compile is deprecated. Use implementation instead."

There is an important functionality involved here: compile has been split into two possible commands: implementation and api.

It is important to understand the difference between those two when you work with libraries. As a oneliner we could say, that "they more or less describe the scope of visibility of your references".

If you use api instead of the former compile for your dependency, everything will work as it did with compile, but all libraries you reference with api are also visible to the users of your current library. This was the same with compile.

If you use implementation the reference is private to your library and users from outside can not see your references. 

A picture tells more than a thousand words:

Image 7

So what does that mean?

  • In the first picture, Libraries A and D reference B and E with the "api" keyword, and so does B with C. The effect is, that your app can use B,C,E without having to reference them.
  • In the second picture A and D use "implementation". They can use their dependencies (of course) but your app can not. The app only has direct access to A,D,F.
     
  • You use implementation when you do not want, that your sub-dependencies can be seen and used from outside your current project.
    • Examples: Your library B is your private toolbox library containing functions that make your life easier, but you do not want to allow "anybody" to use your library. So your library A should make the dependency to Library B as implementation, thus hiding Library B from access in the app. Only Library A can use it.
    • But if you plan a "public api", something that shall be accessed from outside your current project, use make the dependency as api.
    • So the easiest rule of thumb is, to think about the meaning of the words... an api is a programming interface, something you can interact with. If you want that, use api, otherwise use implementation.

Build time

api and implementation can have an effect on the build time of your system. If you use implementation for your sub-projects (B,C) and you change something in one of them, you just need to recompile A and the app can take A as-it-is, because it doesn't care for subs.

With api on the other hand, the app has to recompile B and C too, because it can see all those references and needs to update them too.

So this shall be it for a quick overview. I hope I could give one or two new things to think about and maybe you found something here that you didn't use so far!

History

  • 2017-11-12 - Initial publication
  • 2017-11-12 - Update: Added emulator section
  • 2017-11-14 - Formatting changes and a workaround for a bug added
  • 2017-11-26 - Updated the first Bug description. It is fixed now.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)