The experts’ guide to Android development tools – Google I/O 2016

The experts’ guide to Android development tools – Google I/O 2016

TOR NORBYE: Hello, everyone. Welcome to the expert’s guide
to Android development tools. I’m Tor Norbye, tech
lead for Android Studio. And with me on stage here, I
have a number of key members from the Android Studio team. So do you want to
introduce yourselves? ESTEBAN DE LA CANAL: Hello. I’m Esteban. SIVA VELUSAMY: Hi, I’m Siva. I work on the debugger. KATHRYN SHIH: Hi, I’m Kathryn. JEROME DOCHEZ: And
hi, I’m Jerome, network on the build system. TOR NORBYE: So the
way this is going to work is that we’re
going to show you some of our favorite features and
some features that we think you may not know but that you’ll
find very useful once you do. If you’re an expert
Studio user, you might know some of these things. We want to make
sure that everyone has heard some of these secrets,
even if you already know it. You can be very proud if you do. So we hope that you’ll
learn something from this. And so first we’ll have an
editor demo from Esteban. And then Siva is going to
be showing the debugger. Kathryn, native tools, and
Jerome at the end with the build system. So with that, I’m
going to turn it over to Esteban, who’s going to
be showing the source editor. ESTEBAN DE LA CANAL:
Hello, everyone. We’re going to switch
to the demo machine now. Can you see? That’s good. So in the next 10
minutes or so, I’m going to show you 10
of my favorite features of the editor. You know how coding
all day is, right? One of the things
you try to avoid is touching the
mouse, which is, like, 10 miles away from
where you are, and learning all the shortcuts. So IntelliJ has several
configurations of shortcuts. I will have, when I go through
the demo, all the shortcuts written down there. But there’s one tip. If you’re a
multi-platform, there are two different
shortcut setups for Mac, one that
is Mac-friendly and the other one
that is compatible with other platforms. So if you hear me speaking
shortcuts out loud, I’m probably going to
be using the one that is common across
all the platforms. So let’s begin. Just before we do
the editor part, there are two tips
that I want to show you for configuring the general ID. The first one is the
command line launcher. So I don’t know if you
guys know, but you can go and say, create
command line launcher. And that will create this file
that you can go from anywhere to start Studio. That’s cool. It’s handy. You’re in a console and
you want to start Studio, you just type Studio. That’s pretty neat. But it does more
things than that. So I just created it. I need to put in the password. And done. I’m going to go to the console. If I do studio dash dash
help, that’s the shortcut that I just created. But you can see that there are
more options than just studio. There’s div and there’s merge. I’m have a div
that I ran before. This actually opens studios div. Where is it? It’s gone. This is one of the best
divving tools that I’ve used, and it’s really cool to be able
to have it as a command line tool. You can set it up to your
[INAUDIBLE] tool or whatever, and then you’ll be
using this that you’ll be hopefully familiar with, and
you can use this all the time. You can also do merge from the
command line tool and it works. So that’s one handy
thing you have. The next one I wanted to show
you is you have a large project and effectively, you run
out of memory in the Studio and things go bad. So if you wanted to edit
the memory settings, you need to go to
a VM options file. How many of you have been
to the VM options file and changed the memory? OK, that’s a lot of people. The main thing is that,
where was that file? You’re going to set
things, slash, whatever. So there is an option here that
was recently added that you can say, edit custom VM options. You guys know that you
should not edit VM options inside Studio installation. The next time you update, it’s
going to say, what did you do? So you do this one. And it asks, do you want
to create a custom one? And it opens it up for
you and you can go and set all the flags you want there. If you want to know
where it is– someone was super-excited about this. If you want to know where
it is, you can press Alt-F1, and you can reveal this
file somewhere else. For example, you can
reveal it in Finder. Just pressing 8 or going down
there will open the finder to where this file is, and
you can do whatever you want. That’s for VM options. So we have everything
set up now. And now we’re going to
go into the editing tips. These are my 10 favorite tips
of editing in Android Studio, powered by IntelliJ. The first one is
Control-Shift-J You guys know there are
shortcuts to join lines? Well, this one is a smart one. And if you’re
joining strings, it actually removes the operations
and gives you the full string. KATHRYN SHIH: I think
you lost the ID. ESTEBAN DE LA CANAL: The ID. That’s me. Can we go back to
the demo machine? KATHRYN SHIH: Try
pushing the button. ESTEBAN DE LA CANAL:
Let’s do it again. I was saying talking about,
I’m looking at my screen. I hear it looks beautiful. Control-Shift-J is a smart join. And it removes the
plus operations when joining a string. So that’s pretty handy. There is also the option of–
and this is quite powerful, if you open the intent
menu on a string, a string operation
will plus, there’s an option to copy
the concatenation text to the keyboard. So IntelliJ figured out that all
the components here are static, all the [INAUDIBLE] values. And the full string has been
now copied to the clipboard, and I can paste it here. And it’s the full thing. Operations have been done. [APPLAUSE] Thank you. The next one I wanted to
show is the difference between Enter and Tab. When you want to change a
function– in this case, let’s say we want to
compare two strings, and I’m calling the
function contains, but it should be equals, right? So I type E, it suggests equals. When I type enter, this happens. But you guys know that if you
type Tab instead of Enter, there you go. [APPLAUSE] That’s a pretty handy one to
know because it’s usually, you know, backspace, backspace. The next one I
wanted to show you is the powerful of the
context understanding that the IntelliJ editor has. This is a common pattern, right? You have an object. You say, is this object
the instance of something? If you’re inside this
if, things happen. So if I do oh dot,
the suggestions I get there are not for object. Are for context. So the editor figured
that out and was able to give me all
those suggestions. And as soon as I choose one,
the casting is done for me. More than that, if you are
going to use context many times or oh many times,
opening 10 menu, it’s suggesting to generate
the declaration for you. Done. It actually put the name of
the writer right on everything. Pretty handy, right? These tips are for you guys to
speed up coding. [INAUDIBLE] enter, go go go. So that’s indents
inside an instance of. One of my favorite features
is multi-cursor support. And I’m going to show you
what I do with multi-cursors and how you can integrate
other features of IntelliJ when you have multi-cursors. So I have a list of
names here that I’m going to copy and paste
inside this function. And I want to log all of them. I want to just add a
log D to all of them. You know there is a
completion template for log D. So you can select one and
start spawning cursors on the next occurrence
of the same word. If there is one
that is repeated, you can use a
shortcut to skip it. And you keep going. And now I have all these
cursors that I can do many things at the same time. [APPLAUSE] Thanks. One thing, I can,
for example, say Log D. It suggest Log D.
I can use the template, and it puts it in all the
cursors at the same time. You can use selection per
word, start removing things like this, for example. I’m going to copy. When I copy here, it actually
has one keyboard per cursor. So when I copy, and I go
to the end, for example, and I want to– let’s say
this is an email that I want to complete. And I do– you can
see all the clipboards were different. And in each line, I
pasted a different thing. So I’m like coding at
10 times what I would be coding if it was one line. Another cool thing that
you can do with cursors is, I’m going to go
back to these words. I’m going to select
all the names. And you can use–
Command-Shift-A is a super powerful shortcut. If you want to take one
shortcut away from today, take Command-Shift-A.
That shows you you can choose any action there
and apply it where you are. So I’m going to use
[INAUDIBLE] case. Done. All the selections
have been changed. And I’m logging all the
names pretty quickly. [APPLAUSE] Cool. The next one is navigation. Pretty useful. Command-F12. It shows you all the
functions in your file. One thing that IntelliJ
that is super powerful is, on every menu,
even if you don’t see that there is a search
box, there probably is one. Start typing, and things
happen, like this, right? So if you want to
go to a function, Command-F12, type a
few letters of it. Boom, you’re gone. It is a shortcut to
go back to where you were in navigation shortcuts. There is an another cool
thing that our bookmarks. I use some of these very often. You can bookmark a line, but
this is not the powerful thing. In my opinion, it’s this one. You can bookmark with
Control-Shift a number. And you can give functions
in different files a number. And then, by just pressing
Control and the number, you navigate there super fast. So this is quite handy. If you run out of numbers,
and you want to use letters, you can. I’ve never got that many. But you could use
Control-F11 on Windows. And it opens this menu. You can choose A, for example. And there you go. You bookmark with an A. To find them, there is this
menu that shows you all the ones that you have added. And you can press A.
And it takes you there. So that’s bookmarks. And this one is pretty cool. You guys know that you can
extract a method in IntelliJ, right? So I’m going to go. This is a for loop
that I have there that I would like to be
in a separate method. So I go to the middle of it. And I used the
expression selection tool that it selects an
expression going up and out. So here I have the line. Now I have the block. Now I have the [? eighth ?]. Now I have the for loop. You can go up and
down, depending on the configuration you have. And I selected the for loop. And now I’m going to
extract it to a method. Let’s call method test. What happened? So the font there is too small. But it pretty much says,
hey, stop doing Cut and Paste and write the things properly,
because IntelliJ just detected another
instance of what I had in a different place. So it said, you had
the same method. Do you also want to extract it? It’s not using the
same variables, but it figures out that
if the arguments are the free variables, it’s
going to extract it. And both for loops are gone. And only one test method. That’s the one I like the most. And you clapped on
the Tab versus Enter. This is weird. Perfect. So you know you can do, if, you
have an array or something you can iterate over, you
can do post completion and say, for example, for. And it generates
the for for you. You can also do for I. And this
generates the very familiar for loop that you guys know. And you can also do for r,
and it does the annoying reverse one for you too. There are so many of this. Just play around with them. For example, if
you want an object, to check [INAUDIBLE]
an object [INAUDIBLE], you can just post complete
an n, and it do it for you. And many others like this. If you want to know them,
just press Command-J. No, I didn’t press
Command-J. And it offers a list of all the
completions that you could use on an object. And you can write
your own as well. Number eight that
is pretty useful is, when you have
a condition that is complicated, you
have a lot of Booleans, and you want to simplify
it, just check out what the indent menu has,
because it will have things that will probably help you. So let’s say I want to
replace ors with ands, and this is the result. Or
I want to split into two ifs or reverse the condition. You know, the cool
thing about this is that you’re not
thinking, it just changes, and you know, for
sure, that it’s going to be the same
behavior that you had before. So there you go. A different way of
writing the same function. Control-Space versus
Control-Shift-Space. This is a smart completion. So if you do
Control-Space here, you know that it offers
you all the expressions that you could do there. Not all, but a
big chunk of them. And it chooses the ones
that are correct at the top. But if you do
Control-Shift-Space, it gives you only the ones
that have the correct type. And you can see that before it
was showing the same function as itself. But now it figures out
that, if you do that, you’re going to probably
recur to infinity. So it’s no longer
showing you that. More than that, if I
come on this function here, that is the only other
expression that you could use, and I do Control-Shift-Space,
there you go. It just chose the only one
thing that it could do, and it put it there. So pretty handy. And the last feature that
I want to show you– this has saved me so many times. You know when you say, I’m
not going to commit now, I’m sure it is fine. And then you [INAUDIBLE]? Local history to the rescue. Command-Shift-A, local history. And IntelliJ has
done a div every time you were editing your file. And you have the
history across your day. And you go back
to the point, you say, oh, this is
where I screwed up. And you can see here that it’s
showing a div of everything I did during the demo. Two minutes ago,
I was with this. You can see the joins. This is super, super useful. So I hope you guys enjoyed
this, my favorite 10 tips. And Siva’s going to show
you debugger cool features. Thank you. [APPLAUSE] SIVA VELUSAMY:
Thank you, Esteban. That was a number
of cool features. If you’re like me, you now
have really clean-looking code that doesn’t work. So now you enter the debugger. So let’s spend the
next 10 minutes looking at some features in the debugger
that might help save the day. And I wanted to talk
about, actually, three different things. One is how do you attach
your debugger to a process? And then about how
do you actually set breakpoints in slightly
more interesting ways so that you can narrow down the
area that you want to debug? And finally, once
you’re stopped, how do you examine the
state of your program? First let’s start with
connecting the debugger. The most often used is you
just launch the debugger through Shift-F9, debug app. What this does is it
does a bunch of steps that you specified in
your run configuration. This has a number
of cool features. You can specify what
APK to install and, more importantly, what to launch. So you would normally
launch the default activity. But you can launch
a custom activity if you have activity aliases
or some other activity that you would want to launch. Or you could also launch a URL. But what happens if you don’t
want to launch something? You don’t want to install. You don’t want to build, but
you just want to Connect. Or let’s say someone brings you
a device where your program is stuck in a bad state. So in this particular
case, I have a program. And it’s running over here. And I just want to
directly connect to it. The key is just saying attach
debugger to Android process. This is also present
in the toolbar. When you select
this, it shows you the processes that are running
on your connected device. And as soon as you say,
OK, you select the process, then it immediately attaches
the debugger to that process. Also, this allows you
to examine programs when they are in a messed-up state. So this is good
when your program has been running for a while. Well, what do you
do if, for instance, you want to debug
either a second process in your multi-process
app, or you want to debug
something that is– you want to attach the debugger
as soon as the process starts. So Android has a nice API
called Debug.waitfordebugger. So what this does is that, as
soon as your program starts, if it’s not launched
through the ID itself, when it
encounters this API, it will just pause your
program at this location so that you can
then connect to it. So in this particular case, I’m
going to launch this broadcast reciever. It obviously doesn’t
have to be this. It can be anything. So I go to the shell,
and I launch this. And now you see that the
active– you launched is actually waiting because
it’s waiting for the debugger to connect. At this point, you can,
again, attach the debugger. And now you see
the second process. And this will come force
right at the next statement. So this is really
cool when you have something that you want to
debug really early in your code. So that is how
attach to proceeds. [APPLAUSE] Oh, thank you. Now let’s look at a
few things about how do you set break points in
slightly more interesting ways. Let’s go back here. And let’s run our app. So I have to have a break
point set up that’s, I mean, the application you
saw is a pretty simple recycler view. And if this breakpoint is
set in the bindview holder, it’s going to stop
every single time. So you can continuing, but
this gets super-annoying really soon. So the first thing that
you probably want to learn is there is an option called
New Breakpoints, which will disable breakpoints
throughout your program, all the breakpoints that you’ve set. So this allows your
app to continue running without the breakpoints. And then once you
have your program in a certain state
where you actually want the breakpoints enabled,
you can enable it back again. That is like a hammer. It disables all the breakpoints. If you want to have a
little more control, then you start looking at
conditional breakpoints. What I want you guys to think
of is that breakpoints are not purely static. You get some control
over when they are hit, and what do you do
when they are hit. If you get that part, then you
can just go through the list and figure out all the different
options around breakpoints. The first one, let’s
say, is, I want to say that I want to
break on this location, only on, let’s
say, the 10th item. I’m not sure if that
showed up properly. But I basically said position
equals 10 as a condition there. And this means that
this breakpoint will not be hit until this variable
position has a value of 10. So now I go here, and
I scroll, and now it hits the breakpoint only when
our position is actually 10. That’s the conditional
breakpoint. Now there are actually a number
of conditions that you can set. Let’s go here. And over here, you see
setting a condition is one. Another option
that is really cool is, instead of
setting a condition, you can actually
evaluate an expression. And if you [INAUDIBLE],
then this breakpoint acts pretty much like, every
time the breakpoint is hit, we will just log this
expression over here. Let’s say I want to log
an expression that says, position, [INAUDIBLE]. Can I do this? So now I go to the console. The new feature
in 2.3 already, is that locat gets
streamed directly into your devo console. So you see the locat over here. And then we just
added a breakpoint at the end, which
basically said every time it hits that breakpoint,
it will log an expression. So when I scroll
over here, you will see that, whenever it
hits the breakpoint, it will keep logging whatever
expression that you have given. So this is extremely
useful because you don’t have to– like, if you
just want to log something, then you don’t have to do a
whole rebuild and deploy again. The next– [APPLAUSE] I just want to point out a few
of the conditional options that are there in
breakpoints, which is, there is one cool feature where
you can say that, I don’t want the program to pause
at this breakpoint until a different
breakpoint was hit. So if you specify
this, then the program will pause at this
breakpoint only after the subsequent
breakpoint was hit. And you have even more controls. You know, there are
instance filters. So you can say you
only want to stop if it’s a certain
object, certain class. So now let’s go over from here. So now let’s look at
another really cool feature that the debugger provides. So this is the data which is
displayed by the recycler view. And I have a whole
bunch of objects. What happens if
you want to track one particular object throughout
the lifecycle of your program? [INAUDIBLE] So what I can do
is, let’s say I want to track what is going on with
the eighth object in my list. I can attach a name to it. And this is what you do
by marking that object. And so I say this is day 8. And what that immediately does
is that this is equivalent of you creating a
variable in the debugger and seeing that
this variable points to this particular object. And any time in your program, as
long as that object is visible, you will see it annotated
with this particular name. And it’s really cool
because, many times, you want to track one
particular object. I usually end up writing it on
a piece of paper, the object reference. And you would track it. But instead, you just
have to mark the object. And then, once it’s done,
let’s say you go somewhere else in your program. And over here, you
can actually see, firstly you can see that
it is the same object. So in the case that it is
a singleton, for instance, and you have properly
marked it, you would always see it annotated with this. Not only that, you
can actually use this as a conditional over here. So here I can say, forecast,
[? dot ?] equals, day 8. So this is the
variable name I gave. And the convention is that
you add underscore_debug label as a suffix. And that variable is
just available to you. So now, if you do this, then
we will stop at this breakpoint only until whenever the
forecast matches the daily mark. So this is really
cool when you want to track specific objects over
the course of your program. [APPLAUSE] Now I want to get
into evaluating expressions a little bit. So let’s go over here. So I have this expression. And what this says
is that, if it was more than a day
since the last sync, only then show a notification. But it so happens that I
actually want to debug. So if I continue from here,
if I step through from here, then I go into the if case. But what I really want to debug,
let’s say, is the else case. So now what do you do? Let’s go back to that
breakpoint again. The easiest thing to do first
is you evaluate this expression. So now you see the current. So the result is true. So you’re going to
take the if case. But what I really want
to do is figure out why the if case was true. So now I can see
the lasting time. This is the timestamp
in milliseconds. But it’s pretty hard to see
what exactly that means. So what you can do is,
you can say that I want to view this as a time stamp. Now, when you do
that, it actually renders it as a time stamp. And that’s pretty cool,
because now you see that the last sync was at noon. And so, obviously, the if
condition will always be true. Now comes the next part. You actually want to force it. So what you do is you
set the value to 0. And you close. And then you can evaluate
the expression again. Now the result is false. And that’s because we were
basically just able to, from the debugger, set
the value of an object. And you can do this, actually,
for any field that you want. So now, if you
close and step, you can now get the else
case without actually tweaking your program. You just change the
value in the debugger. The last couple of things. So actually, let me show
one more thing here. Smart step. So normally, when you
have code like this, which is either
methods, which are– so I have a method like this. Then typically,
if I want to step into one of these methods,
what used to happen is that, you would actually
have to step into each one, and then you get out of it,
and then you go back into it. So instead, there is an option
called Smart Step, which will tell you exactly
which particular method you want to step into. And this is really useful
whenever you have methods, you know, functions
being passed in. So you have multiple parameters
which take function values. And then you can select
which particular method you want to step into. Now let’s look at a little
bit about the view over here. In this stack frame
view, everything that is colored
yellow is actually coming from sources that
are not in your project. One tip to know is that,
earlier, so if I select this, we would take you to
the platform sources. But the platform sources always
corresponded to your target API level, not corresponding
to the device that you’re actually running on. Finally, in 2.2,
we have fixed it so that we now show
you the sources corresponding to the device. The only thing you
have to do is make sure that that particular source
is actually installed. We don’t have a UI
that comes up and says that, if you install
this, it will properly show you the source. So just as long as you
have the sources installed, it will pick up the
correct sources. [APPLAUSE] Thank you. Finally, I want to say a couple
of things about Instant Run. One really cool thing
about Instant Run is that, if you are debugging,
and instant run is enabled, you can actually restart
an activity from here. And that would immediately,
if I had launched it in Instant Run mode,
it would pretty much restart the activity. You don’t have to go kill it. You don’t have to
go to the device. And one other tip when
you’re using Instant Run is that you have to
manually use the stop button to terminate the application
before running again if you want to launch
to a different device. This is just a little bit of it. Because Instant Run in new, many
people get confused about that. That’s what I had. Hope you found it useful. Next up is Kathryn, who
will talk about C and C++. [APPLAUSE] KATHRYN SHIH: Awesome,
thank you, Siva. So C and C++. I’m going to cover
a little bit of edit and a little bit of debug. So, on the Edit front, if
anyone’s ever edited mini JNI methods, it’s
really, really easy, when you author it
in the C or C++ side, to get some name mismatch. And then you get
some runtime error. We’ve actually got
functionality in Studio, though, where you can completely
avoid this problem because when you start creating a
new method, let’s just make a clone of our
string to JNI here, you can auto-complete
it from the Studio side. Oh no, where’s my button? And it creates a
whole stub in C++. So don’t have to worry at all
about whether you’ve actually gotten the right
Java classpath here. Once you start editing, there’s
a C++ tool called Oxygen, where it gives you
Java style autodocs. So let’s say we want to
create some sample function. I’m going to add
the method– or not. Hey, whatever. So as I create this, I can
put whatever I want in there. And then you can look
up the whole list, but a couple good
ones are brief is the heading, this is what I
do, and say author, param. And then, when you
go down and hit F1, I should, if I have
spelled this correctly? AUDIENCE: [INAUDIBLE] KATHRYN SHIH: Sorry? AUDIENCE: [INAUDIBLE]. ESTEBAN DE LA CANAL: Small s KATHRYN SHIH: Oh, gosh. So once I actually get
my letters correct, you can see all my docs. Return is another
super-handy one. Your stuff right. And yeah, it’s a good
way to get Java style, keep track of things. You don’t have to tab back
and forth all the time. Once you’re done editing, we’ve
added a bunch of functionality to the debugger for C++. So I think, in the
earlier talk, Tor mentioned the auto debugger. And I’m just going
to start this. If you ever start the debugger
hoping to catch C++ code, and you’re like, why is it
not catching any of my native breakpoints, the first thing
you should always look at is, under your app configuration,
do you have it set to Java? If it’s set to Java, you’re
going to be pretty sad. But when it’s set to
Auto, Native or Hybrid– well if it’s set
to Native, you’re not going to catch
any Java breakpoints. But I can step into
my Java breakpoint. And then I can actually
see a little-known feature called a Memory Watchpoint. So I can right-click on this
and say, Add Watchpoint. And this actually
adds hardware support where, whenever I touch
this memory address, it’s going to stop the debugger. So let’s set this
to NE, because I’m going to be reading from it. And you can see, I don’t
have any breakpoints set down here– oh, just
one at the very end. I start running. And since we’re actually
accessing the memory where I set the breakpoints,
the CPU is going to stop and let us
look at it with a debugger. So if you ever try
to figure out what’s going on with some
crazy chunk of memory, this is a really
handy way to do it. It’s officially supported
on x86 and the Nexus 9. The emulator,
though, is a good way to get an x86
debugger environment. So once you’ve done that,
let’s take that away. And the other thing we’ve added
to the debugger for C++ is STL support. So you can see, up here,
I’ve created a vector, and I’ve added a
bunch of pairs to it. I can actually start expanding. It’s fully aware of the STL. You can have some
crazy map in here, and it should still render. And you can interact with the
STL when you’re evaluating your functions, like [? vec ?]
[? dot ?] or size, and voila. Similarly, you should be able
to edit memory, see the results. So I think that’s the
debugger stuff we’ve added. Let’s see if I can
get us back on time. Oh, and then the other thing I
should’ve mentioned under Edit, if you’re used to using C++
11, you may have noticed that the NDK and experimental
Gradle do not default to it. So you’re like, auto,
variable, error. A handy way to fix that is
you can actually turn it on. So if you’re using the
experimental Gradle plugin, and you want to use C++ 11, just
add this to your NDK stanza, and you will have access to
all of the handy 11 language features. And then a final tip for C++
is, if you ever have a JNI error on a debug build in
studio on an emulator, you may notice that you get
this expanded stack trace. So I have an app here that
is actually probably not very social. It’s got this handy
button for a Crash JNI. And if we hit this–
let’s just keep going. If we hit this, it actually
makes a invalid JNI call. So we can’t call Find Class for
something that’s not a class. And we’ll get this
huge stack trace. I know some folks
have come saying I’m getting all these [? sick ?]
aborts for my production build. What’s happening? One thing to consider is that
these stack traces actually only occur on debug
builds from Studio by default and on the emulator. If you’re using a real device
for the production build, all you’ll see is the abort. And there’s a handy
way to fix that, which is you can connect
to a device with ADB and set check JNI to be one. And this will
enable JNI checking, even if it’s a
production build, even though it’s physical device. So you’re seeing crazy aborts
coming out, try running this, and try using it to
see if you’ve got a JNI problem causing your error. And with that, I’d like
to hand it over to Jerome for some Gradle tips. [APPLAUSE] JEROME DOCHEZ: Thank you. All right. So as you know,
we’ve worked a lot on performance of
build, whether the build should be incremental or full. And some of the effort that was
led by this performance work was the Instant Run technology. Now, when Instant Run got
delivered, a lot of people got confused about a few things. And I would like to
clarify some of them today. So first of all, the
way we do Instant Run is by doing [? bicode ?]
instrumentation. And we do had a few
fields and a few methods. So suddenly some
magic can happen, and you can reload a class in
your living virtual machine without having to
restart the application. Now, this adding of
fields and methods have sometimes thrown people
over the limit of the 65k text file limit. And a lot of people
were confused by that and not knowing how to fix it. So I thought I should
explain how it is. So basically, if you hit
the 65k limit, which is just what happened here–
I should probably make this a little
bigger– so you should get a message that
will tell you that you are over the 65k limit. So, as you know,
the text file format only supports 65k
methods or classes. Here I am at 70k. So to fix the
problem, I just need to define one more
Gradle thing to say, I want multitext to be true. OK? So when that happens, and
now we can try to build, Gradle will start
saying that we are lowering to build
the application in separate
different text files. Now there’s two types
of multitext platform. There’s what we call
the legacy multitexting. And there is the modern
or native multitexting. And depending on which
platform you’re targeting, you will use one or the other. Basically, before 21, you
will use the legacy one. And 21 and above, you
will use the modern one. The problem here is that,
because we are targeting mini SDK 19, by default, the
legacy multitext will be used. So we’ve still got
to build, and it’s 12 seconds, which is going to be
our baseline for today’s demo. And we’re going to see
this number going down as I’m starting to improve,
by different settings, this build environment. But first, I would like to
change a little bit of code, just one line. And I’m going to change
this, for instance. So we also get a baseline
for the incremental build. So the incremental build,
we just have one file. In theory, it should
be much faster. But we’re going to see
that, because we’re using legacy multitext it’s
not going to be much faster. In fact, it might actually
be more or less exactly the same time. 11.5, OK. So we are 12 for the full build. 11.5, for the incremental build. I cannot say that we are doing
a great job at the incremental building here. So first, what we
should do is to try to switch to native multitext. Because with native
multitext, the virtual machine is capable of
understanding, natively, that an application can be
packaged a simple text file. And therefore, it’s a
lot less work for the build system to be
able to handle this. So to do that, we’re
going to add a flavor. And this one is going to
be said the legacy one. And that’s where we’re going
to continue targeting 19. And then we have a
new flavor that we’re going to be calling Modern. And this one will be
targeting 21 and above. Now if I go to the build
variance– let’s think first. If I go to the
build variance, I’m going to switch my legacy
debug to my modern debug. So now that I’m
going to rebuild– do not ask me this
again, please. When I’m going to rebuild,
I’m going to now rebuild with the modern text file. And that’s not going to make a
huge change for the full build. So let’s wait until
it’s doing its job. 11.6, we were at 12. So it’s not great. But slightly better. But where we are going to
start seeing a big difference is when we do the
incremental build. So when the incremental build,
we were also at 11.5 seconds. Now we’re at six. So we already divided
by 2 the build time. That’s good. But I’m sure we can do better. Keep your claps for now. First thing that you
should always try to do is to use the latest
Gradle plug-in. Because we always
try to enhance stuff. Yes, sometimes we break
stuff, but we try to fix it. But, for most of the time,
we try to make things better. And using the latest
version will allow you to use the latest enhancements. So, in this case I’m going to
switch to the latest version. And I’m going to continue
building exactly the same way. But because I want to
force a complete rebuild, let me clean it first
and run a full build. So here, I’m getting
another type of message. And it’s telling me
that, starting with 2.2, we make things better. You can now run your
decks in process, which is going to make things faster. But, unfortunately, in
this particular instance, you don’t have enough memory. And therefore, we reverted to
the old out of process stuff. So let’s add more memory
to the Gradle daemon. And I cannot stress how
important this can be when you will start using the Gradle 2.2. You should really look
into adding more memory to the Gradle daemon. So here I am adding 4G. And I’m going to do exactly
the same thing again. I’m going to clean the project. So we get a new baseline
for the full build. So in this case, the
message should be gone. And it is gone. So now we are in process. And we were, about
12 seconds earlier, we are down to nine
seconds for the full build. It’s pretty OK. Let’s continue trying to see
how much it would take to make an incremental change now. All right, 2.3 seconds. It’s getting better. But we can do more. [APPLAUSE] No, we can do more. Next thing, Instant Run
has been disabled so far. So let’s put it back on. So when it’s on, we
will try to redeliver the smallest set of changes
each time you do a build. So again, let me
clean it so we are sure to have a
clean environment. So Instant Run will
not only try to reload a class in the virtual machine
without even restarting the application, but it will
also concentrate very much into route delivering the
minimum set of changes required. So in this particular
case, excuse me, in this particular case,
when you change a single Java file, it will most
likely only redeliver the text file that corresponds
to the single Java file. So that was the full build. Now let’s change again, this,
and let’s measure how much. We are down to 0.6. Now we’re talking! I’m pretty sure. [APPLAUSE] Even better, I can go to 0.4. OK, so, as you can see,
we start at 12 seconds. We are now at 0.4. With very little changes,
very little work, we divided by more than
20 times the build time. But let’s do some other changes. For instance, let’s take
the source files here. And let’s look
into the main file. This is really small here. Actually, I don’t
have to do this. I can go to the app. So as you can see here, I’ve
got a version code, which is 1. Let me change it to 5. And let’s see how that’s
influenced the build. 3 seconds, what happened? I was at 0.4 And now
I’m at 3 seconds. Well, what happened is that
we changed the main manifest. And when that
happens, the only way we can redeliver
the manifest file is by redelivering the full APK. So you can see how some of
the changes that you make have a very strong influence. And knowing the tool,
knowing what the tool does, is very important. Here, if you, for
instance, are smart and try to change the version
every single time you build by using the current time,
right now, as your version, you’re going to see
that you will never, ever leverage
Instant Run features. So it’s important
to remember that. But again, on the
standard tools. There’s a lot of documentation
about the Instant Run. I’m afraid we don’t
have time for QA. We have only 30 seconds. But we will be available
outside for QA. And then we have
the booth, which is right outside on this side
for the Android Studio, where you’re more than welcome to come
and ask for further questions. Thank you very much. [APPLAUSE]


13 thoughts on “The experts’ guide to Android development tools – Google I/O 2016”

  • I would love to switch to AS, but since it is not possible to have (at least for an intervening period) both Eclipse and AS in parallel, I can not switch. If something does not work, I have no basis to maintain my game, because Eclipse is no longer working. They should be able to separate AS and Eclipse stuff, so that both can coexist for the time beeing.

  • Liran Barsisa says:

    Some comments:
    4:40 – wish I could do the same for all fields of a class, which is useful for "toString()" and logging, for easier debugging and checking the content of variables. Same goes for cursor fields and values.
    12:00 – wish I could do the same for cursors, so that I could iterate over each of the query's items.
    13:54 – wish CTRL+space would be the default one to show the smart results. There is no way that a function that returns void should fit in there.
    14:55 – sadly sometimes it forgets about changes. On Eclipse, it could remember changes for a very long time. I can't find a way to customize it to show changes for a long time.
    16:22 – wish I could customize what to add to the intent, so that I could customize it and send special things to use.
    17:53 – I think it would be better to auto-add breakpoints to all "waitForDebugger", or at least an option to do so. Also warn when signing an app with this call.
    38:51 – wish it would be automatic, based on which device is currently attached.
    40:34 – actually the "" is quite buggy. It somehow causes some 9-patch files to not appear well (or at all). reported here:
    44:19 – does this mean that even if the APK file name is created using various things (like timestamp), it will ruin how instant-run feature works?

Leave a Reply

Your email address will not be published. Required fields are marked *