Architecture Components – Introduction (Google I/O ’17)


[MUSIC PLAYING] MIKE CLERON: So hi. I’m Mike Cleron. I’m on the Android team. I manage the system UI framework
and UI toolkit teams there. We’re going to be talking
today in a lot of detail about some big changes to
how we recommend that you build Android applications. But before we go into
a lot of the details, I thought would be helpful
to step back a bit, and frame the discussion by
talking about where we came from, and where we’re going. So let’s do that. So to start, Android
has always been based on some strong principles. Not surprisingly, those
were best expressed by Dianne Hackborn. She’s the one who
actually architected most of the Android framework. She wrote a post about
this a few months back, and I have some
excerpts from that here. If you look at our
core primitives– activity, broadcast receiver,
service content provider, you might reasonably think that
those constitute an application framework. But that’s not the right
way to think about it. These classes are
actually contracts between the application
and the operating system. They represent the minimal
amount of information necessary so that the OS knows
what’s going on inside your app so we can manage it properly. So as an example, if your app
is running in the background, but is also exposing data
to another application through a content provider,
the OS needs to know that. And we need to know that so we
don’t accidentally kill you. The content provider is a
mechanism that tells us that so that we can keep you alive. So we think of
these core classes as really being like the
fundamental laws of physics for Android, hence
the illustration. That is the cover
of the manuscript where Isaac Newton
first presented the basic laws of motion. Now, fundamental laws
are a good thing. I use a shorthand when
talking about this. I say, Android has good bones,
even though people look at me funny after I say that. But what I mean by
that is that Android is based on a small,
stable, cohesive set of core primitives. And that allows a
common programming model across a really
incredibly diverse range of devices from wearables
to phones to tablets to TVs to cars, and more. This model also gives
application developers the freedom to choose
whatever framework they want inside
their application for their internal framework. So that means that we
on the Android team don’t have to get involved
in debates about whether MVC is better than MVP, or whether
MVP is better than [? MVVBM. ?] You guys can pick whatever
makes sense to you. Now, that’s a pretty good story
if you are in the operating system business like, say, me. But if you’re in
the app development business like, say,
all of you, that’s really only chapter
one of the story. And the reason for
that is because while strong fundamentals
and freedom of choice are good things, we know that
in your day to day jobs– and we know this because you
told us, you want more from us. So I’m going to abuse
my analogy a bit here. We can all appreciate the
simple elegance of Newton’s laws of motion, but if your job
is to land a Rover on Mars, you don’t want to
come to work each day and start with only F equals
ma, and derive everything from first principles. So we’ve been talking to
developers, both inside and outside of Google, and
taking a hard look at the app development experience. And we’ve realized
a couple of things. First, there are
peaks and valleys. Some aspects of app development
are better served by our APIs than others. For example, we think
RecyclerView is that the better end of that spectrum. So with RecyclerView, we didn’t
say, hey, we give you events, and you can draw stuff. And in between you have a Turing
complete language, so good luck with everything else. On the other hand,
maybe Activity and Fragment Lifecycles belong
down in that dark shadowy place because there, I
think, too much of it is indeed left as an
exercise for the reader. And we want to fix that. So as we thought about this,
we realized the good solution has key properties. First, we have to solve
the right problems. This is going to be
a sustained effort– like sustained
for us on Android. But for the first cut,
we want to make sure that we are going
after the problems that every developer
faces, the things that are hard to do right right now. Again, app Lifecycles is
a really good example. If you don’t get that
right in your app, nothing is going to
work on top of that. And that’s true for your
app, but that’s also true for the frameworks
we’re trying to build. We have to get that right
before we can do anything else. Second, we have to
play well with others. We know that you all have huge
investments in your existing code bases, and we
can’t create a model where the first thing
we say to you is, throw all that out
and start over. So we’re trying to create APIs
that you can adopt a little bit at a time, and also
that interoperate well with other libraries
or other frameworks. Third, we want to
be more opinionated. We’re going to take a
stronger, clearer stance on how to Android and
app the right way, at least as we see it. Now, this is all still optional. And if you already have
something that works for you, then great. But developers are telling us
that they want more guidance on how apps should be
built. And by the way, we’re not changing any of
the laws of physics here, we’re just layering some
higher level constructs on top. Because after all, F is
going to equal ma whether you believe it should or not. Next, it needs to scale. We want solutions that
are industrial strength, and that will scale to the
real world requirements of real world applications. We don’t want to build something
that’s awesome for Hello World, but then it’s going to
collapse the first time it bumps into the messy
complexities of reality. And finally, reach. For this problem,
for making it easier for you to write Android
applications the right way– what we think is
the right way, we want to use libraries like
Support Lib wherever possible rather than adding new
APIs to the platform, because lets our solution
reach older versions of the OS as well. OK, so that’s the background on
what we’re trying to accomplish and why we’re here. Now we’d like to introduce
Yigit, tool kit engineer extraordinaire, and he’s
going to walk you through what we actually built. Thank you. [APPLAUSE] YIGIT BOYAR: All right. Thanks, Frank. Hello everybody. So that was the background. What are we shipping today? The very first thing
we are shipping is an architecture guide
on developer Android com. Now for over years, you’ve
been asking us for our opinion. Like how do we think that an
application should be built? And this is that guide. So we believe that
it’s very good, covers lots of
application cases. But even if you
have an architecture that you are comfortable
with, you can keep it. But you can probably learn
something from this guide. Second, we are shipping
a new set of libraries that we call
architecture components. These are more
fundamental components where you can build
your application on top. The first thing is Lifecycles. So this is the biggest developer
complaint that we have. Lifecycles are hard,
Lifecycles are hard. And we said, OK, we
should solve this problem. And the first level of this,
this new set of components. Second one is
Lifecycle-aware observables, which will go in detail
later, but this is basically things that can do something
based on the Lifecycle. Third, we are going to introduce
a lightweight ViewModel, which is all of our effort
to take out that code outside of your
Activities and Fragments, and put it somewhere else
where you can easily test it. Last but not least, we are
going to introduce a new object mapping library for SQLite. And all of this is available for
you today on Maven Google com. [APPLAUSE] Let’s talk about Lifecycles. So what is what’s
hard about Lifecycles? Why do we hear so many
complaints about that? Let’s go through an example. Assume we have an
activity where we want to show the location
of the device on the screen. So you will try
something like this. You create a LocationListener
on Create method, you need to initialize
it with the context, and you have a callback that
it calls whenever the location changes, and you update the UI. Now, if you have ever written
an Android application, you know that this
code is never enough. You also need to go ahead and
override onStart, and then tell it to start, and override
onStop, and tell it to stop. You always need to
do this babysitting for these components. But this is acceptable. This a simple example,
this looks all right. But then your product
manager comes and says, oh, you know what? We need to first check the
user settings before enable– asking for a location. Then your developer says, OK,
sure, that’s an easy change. I’m going to change this method
to first call this utility method, which probably
makes a web service call to check the user settings. And then if the
user is enrolled, then we want to start
the LocationListener. Which looks like a
very simple change, you will think this would
work, but let’s look at what happens in that
activity’s Lifecycle. So our activity was created. We said, OK, run start check
if the user status is enrolled. Then meanwhile, user wants
to rotate the device. Which, rotation means
a configuration change, which means Android is going
to recreate that activity. So in onStop, we
knew about this, and we said, OK,
location manager stop. And then the new
activity came, it also goes through the same thing. Looks all right, except
do you remember this call we made before? That little change, and then
it decides to come back. Hey, user is enrolled. And then what we did? We said, OK, then start. And you realize the [INAUDIBLE]? We called start after
calling on stop, which means our activity will live forever. We are going to observe
the location forever, the battery will drain. We will have sad users. This is situation, right? We want to get rid of this. We want to put an end to this. So we said, OK, we
need to acknowledge– like as Mike mentioned,
we cannot change the laws, but we can make it easier
to deal with these things. So we decided to introduce
a new interface called LifecycleOwner. This is a thing
with a Lifecycle. Is your activity, is
your fragment– or maybe you have your own UI framework,
whatever the container you have there as a LifecycleOwner. And we have these
LifecycleObservers, which are the things that
care about the Lifecycle. Like the
LocationListener we had, it cares about the Lifecycle,
it wants to stop itself if the Lifecycle is not active. So we said, OK, we
will acknowledge this. And we have a
LifecycleObservers. And we’ll go through the
code through our activity. Now we make our activity extend
the LifecycleActivity class. This is just a temporary
class until these components reach 1.0. Then everything
in Support Library will implement this
LifecycleOwner interface. Inside of our activity,
when we initialize our LocationListener,
we are going to tell it, this is the Lifecycle
you care about. And that’s all we will do. But as it’s the same, it
calls back the update UI. So how can we change
our LocationListener to take advantage
of this Lifecycle? Oh, we do the same thing
for the UserStatus as well. So there’s some boilerplate
code here to get the fields. It doesn’t really
matter, but we have this enabled method which gets
called if the user is enrolled. Inside this enabled
method, now we want to start
listening to location only if the activity is started. Now you can do this. You can say, what is my current
state, which is amazing. We didn’t have
this API until now. Well now you can. So OK, that was a simple change. But we also get
notified, what if we get enrolled when the activity
was in back state, and user comes back
to the activity. Now we should actually
start the LocationManager. For this, we want to
observe that Lifecycle. To do that, we implement
this interface, which allows us to
write these methods. You can annotate
the methods saying that, if ON_START
happens, call this method. And the new components will
take care of calling you. So if you are already
enabled, now you start, and ON_STOP
you disconnect. And last but not least, if
the activity is destroyed there is nothing you want
to do with that activity so you can unregister. So now you might be asking
yourself, well, you just moved those ON_START, ON_STOP
methods from the activity into this Location Manager. How come it is simpler? It’s simpler because
those methods live in the right place. It’s the Location Manager which
cares about the Lifecycle. So it should be able to
do it without the activity babysitting itself. I’m sure if you look
at your code today, your activity ON_START, ON_STOP
methods are like, at least 20, 30 lines of code. We want them to be
zero lines of code. If we go back to
activity, I want to point out something that– look, in onCreate, we
initialized these components. And that’s all we did. We didn’t override, we
didn’t ON_STOP, ON_START, we don’t override
any of those things because the Location Manager
is a Lifecycle aware component now. So it’s a new concept
we want to introduce. A Lifecycle aware component in
a component can get a Lifecycle, and do the right things. It can take care of itself
so that your activity, you can just initialize
it and forget about it. You know that’s not
going to leak you. Now, of course, it was like
more of moving the complex from activity to the
Location Manager, and then it still needs
to deal with Lifecycle. We said, OK, what do we want? It’s nice to be able to
do that, but we want more. We want a very convenient
to handle this common case. It’s very common that your
activity or fragment, it observes some data, and
whenever that data changes, it wants to refresh itself. It happens basically
almost every single UI. And we want to share resources
across multiple fragments or activities. The location of the device
is the same from fragment to fragment. If you have two
fragments, why do you need to create two listeners
to listen to the same location? Hence, we created this
new LiveData clause. Let’s look at that. So LiveData is a data holder,
it just holds some data. It’s like an observable, but
the tricky thing about LiveData is that it is Lifecycle aware. It understands about Lifecycles. Because it understands
about Lifecycles, it automatically
manages subscriptions. So very similar to
the previous example, if you are observing a LiveData,
you don’t need to unsubscribe, the right things will
happen in the right times. So if that LocationListener
was a LiveData, and a singleton because location
is singleton, we could write the code like this– get distance, start observing. And when you observe, you
say, this is my Lifecycle. This all you need to do. Before on Android, if you were
observing something singleton from an activity, everyone
will give minus two to that code review. Now you can do this. This is safe,
nothing ever leaks. So if you want to change
your LocationListener to use this new API, we get
rid of the unnecessary things. All we need is a
context to connect. What we say, this is a LiveData,
this a LiveData of a location. And we get these
two new methods. One of two says
onActive, which means you have an active observer. And the other one
says onInactive, which means you don’t have
any observers that are active. Now at this point, you’re
probably asking yourself, what is an active observer? Well, we define
an active observer as an observer that’s in the
STARTED or RESUMED state, which is like an activity user
is currently seeing. So if you have an observer
in the back stack, there’s no reason to
put this inactive. There’s no reason to
update that activity because user will never, ever
see what’s going on there. So inside our connect
method, all we need to do is, whenever the system
Location Manager sends us a new location, we call
setValue on ourselves. Then the LiveData knows which
are the active observers, and delivers the data
to those observers. Or if one of the observers
was on the back stack and then becomes
visible again, LiveData takes care of sending the latest
data back to that observer. And then we can make our
LocationListener singleton because well, we don’t
need multiple instances. So if we look at LiveData, it
is a Lifecycle aware Observable. It is very simple start
and stop semantics. Doesn’t matter how many
observers you have, or what state they are, we merge
all of it into one Lifecycle. And it doesn’t have any
activities or fragments inside it, but it works
with both of them. And is also really used to
test LiveData because it’s kind of Android free. And if you know about this
infamous FragmentTransaction exception, we guarantee that
your observer will never, ever be called in a state
where you cannot run a FragmentTransaction. So this is very, very
specifically designed to work well with your
Activities and Fragments. OK, let’s think about
configuration changes. Now, that example was easy
because location is global, but most of the time,
the data belongs to a UI. So if we had an activity
where we show a user profile, and we implemented
a web service that can return the data as a
LiveData which we can safely observe without risking
leaking overactivity, this all looks nice. You will never
leak this activity, it will work very well. Except, what happens if the
user rotates to the device? Let’s look at the
LifeCycle graph again. So activity is
created, it saves, OK. Fetch the user. And then while you
are fetching the user, user decides, oh, I want
to rotate the phone. And then that
activity is destroyed. Luckily we don’t leak
it, which is great. But then the new
activity starts, which makes this new call. Now, this is OK, but not great. What do we want? We want to actually
retain that data, right? We are already making that
request, why remake it? So we want our graph
to look like this. So if the new activity
comes, we should be able to give it back the
same view model, which is a new class called ViewModel. So we are introducing
this new class very specific to
this thing, where you should put the data
inside your activities into the ViewModel, and make
the activities data-free. So if you want to
change this activity, we create this new class, it
extends the VewModel class. Whatever data we had inside
the activity, we move it there. And in the ViewModel, all we do
is, inside the getUser method, if this is the first goal,
get it from the web service. Otherwise, return
to existing value. Now, super simple. And inside our activity, we
get rid of all that code. We say, get the
ViewModelProviders.of this. So each activity or a fragment
has a ViewModelProvider that you can obtain, and
that ViewModelProvider knows how to give you the ViewModel. So when you call
get MyViewModel, the very first time
you make this call, we will give you a new instance. When the rotated
activity comes back, it’s going to reconnect
to the same ViewModel. And then the rest of
the code is the same. [APPLAUSE] So if you look at the
Lifecycle, this is how it looks. This is what we wanted. The new activity is
started, it reconnects. And when the new
activity is finished, like when we don’t have anything
to do with that activity, and then we go
and tell ViewModel that it’s not needed anymore. This is actually the only
method in the ViewModel class. So this is very simple. So if we look at
Lifecycles, they hold the data for the activity. They survive
configuration changes. They should never,
ever reference views because they [INAUDIBLE]
leave the activities. So you cannot reference
back to the activity. That’s why you use
things like LiveData, Rx Java, or
datamining observables to do that communication. And this is what our
activity talks– it always talks to the ViewModel. Now, another big
topic is persistence. Now, we know that to write a
good, responsive Android app, you need to save
the data on disk. If you come to Android, there’s
this three major APIs we have. One of them is content
providers, which is to talk between processes. It really has nothing to do
with persistence, in reality. The other one is
shared preferences, which saves the data in XML. So you can only put very
little data into that. And the last one
is SQLite, which is something we have been
shipping since Android 1. So you know you
need to use SQLite if you want to save big data. And so you go into the
developer.android.com/ This is the very first saving
your data slide. This is so confusing. This is very sad. [LAUGHTER] So is it– OK, we want
to make this less sad. We want to make it happy. So we’ll look at
the example, right? So there’s– on top,
it tries to say, I want to select these three
columns with this constraint, and I want to order
them like this. This actually really,
really simple SQL query, but you need to
write all this code. Plus, this code
doesn’t even show where you define all those constants. So what do we really want? We want to get rid of that
boilerplate-free code. When you are writing Java,
if you make a typo in Java, it doesn’t compile right. We want the same thing for SQL. We still want to use SQLite,
because on every single Android device it’s a proven technology. We know it works very well. But we want the compile
time verification. So we don’t want the
boilerplate code, we want to compile
time verification. So we said, well– we came up
with Room, which is an object mapping library for SQLite. [APPLAUSE] So if you look at
this query, we said, OK, let’s move this query
inside the annotation. We like annotations. And we have this
feed object, which we want to save in the database. I want to put that query
inside an interface. You want to create the FeedDao– the Dao stands for
Data Access Object. Usually in database, the best
practice to put your database access into certain interfaces. Then we just need to tell
the Room, this is a Dow. Tell Room this is an entity. And finally, we had a
database class which says, I have these entities– so
you have multiple entities, and I have these data access
objects, as you saw them. This is all you write. Once you write that, you can
get an implementation of it from Room. It’s very similar to how
you use Retrofit or Dagger– you define the interfaces, we
provide the implementation. Now, once we know
this is a Dow, we can do these shortcut methods. Like, insert these items, or
delete these items, or update– a bunch of shortcut methods. And you can press
multiple parameters. As long as you can read
it and it makes sense, Room will understand it. But the most
important part of Room is, it understands your SQL. So the part– all
those constants I mentioned we defined to
get compile time guarantees, Room actually gives
all of this for free. So when Room sees
this query, says, OK, you are receiving
these three columns from this table where the
title looks like this keyword. Where is this
keyword coming from? Oh, it’s coming from
the function parameters. Makes sense. And what does it want to return? It wants to return
a list of feeds. And then Room goes and checks. Does the columns
returned match the object the user wants to return? And once they’re equal, it says,
OK, I can generate this code. You can have even
say, select star. You don’t need to list them. Room really, really
understand your query. You can even join 10
tables, it will still work. But what if you made a typo? Instead of saying feed
table you wrote feeds. Now, if this happens,
Room is going to give you an error at compile time. So it goes out and
verifies your query against the schema
you have defined, and it tells you if
something is wrong. [APPLAUSE] But that’s not the
only thing it does. So if you said– if your query is correct, you
want to fetch ID and title. This said, well,
it’s query, but you want to return it as a string. And then Room says, well, you
are returning two columns, but you only have one string. That doesn’t make sense. And it’s going to give you
a compile time error again. And there’s a really nice
way to fix this in Room. You can basically
create any Java class. It doesn’t need
to be annotating, there’s nothing special
about that Pojo, and tell Room to return it. As long as whatever
query it returns matches what you
want it to return, Room will write
the code for you. And observability, which
is very important, right? If you have a query
like this, now you’re showing lists of
feeds, you obviously want to get notified
when the data changes. And in Room, if you want to
do this, all you have to do is tell it. Tell it to return a LiveData,
and it will do it for you. Because it knows your query,
it knows what things affect it. So it can let you know
if that query changes. And this is the part where all
these architectural components work well together. Room already knows
about LiveData. So your ViewModel, all you would
write is– from the data is, call this query, and
this all it will do. Whenever that data changes,
your UI will get a new update. And it only happens
if the UI is visible. Last but not least, Room
also supports RxJava 2. [APPLAUSE] OK, if we look at
Room in a nutshell, it writes the
boilerplate code for you. It has full SQLite support. You can just write in
SQLite, there’s no builders. It verifies your
queries at compile time. It incentivizes best
practices, which helps you with testing migrations. And it’s also observable
out of the box. OK, architecture,
our last topic today. So where we started, right? And now, you might
be asking yourselves, what has changed
in 2017 that you are talking about architecture? Well, actually
nothing has changed. We’ve been talking
about this topic a lot. Adam Powell and I gave a
lot of talks on this topic. There’s even a talk from 2010
which I watch as a developer. So this is a topic we have
been more clear about. But what is missing was
a well-defined reference architecture. So it’s what we
are shipping today. If you go to
developer.android.com today after the session,
there’s a section about how to architect
an Android application. [APPLAUSE] So by the way, this
is a reference guide. This is not your religious book. We believe this is a very good
way to write applications, but you don’t need to
follow it line by line. So I’m going to briefly go
through this architecture, but if you get
lost, don’t worry. We have all of this documented
on developer Android com with sample applications. So we think that
an application is composed of four main things– there’s UI controllers, the
view models, a repository, and the data sources. So let’s look at
these in detail. UI controllers are
your activities, fragments, custom views. They have really simple tasks. They observe the
fields of the ViewModel and update themselves. And they want more
responsibility. Whenever user takes
an action on the UI, they understand that action,
and call the ViewModel to express whatever
the user wanted to do. If you go to our view
model, view model is the one which prepares
the data for the UI, and holds onto it. This is where the
data for the UI lives. View model knows how
to get that data. Usually it has LiveData. If you are using Rx
Java, it is observable, or datamining observables. It survives
configuration changes. That’s why we put the
data into the view models. And it is also the gateway. You can also consider it
as, your UI controller only ever talks to the
view model to reach to the rest of the application. And then what’s the repository? Now, the view model
serves as a data store for your UI controller, right? Repository saves
it as a data store for all of your application. So it’s the complete
data model for the app, and it provides this
data with simple APIs to the rest of the application. You can have a user repository
where you pass a user ID, and it returns your
LiveData of users. How it gets the data? You don’t care, it’s
the repository’s job. So how does it do that? It talks to the– fetching, syncing,
looking at database, or talking to your
retrofit back end. It’s the repository’s job. And last but not least,
we have our data sources, like your REST API client. You might be using Retrofit,
or you have SQLite storage. You might be using Room,
or you might be using GRAM, doesn’t really matter. Or you might be talking
to other content providers from other processes. These are things we
call data sources. And we think that
all of these layers can discover each
other to create dependency checks
to the system which we’ll command using Dagger. But we also realize that
understanding dependency situation is not very trivial. It’s a more complex topic, and
sometimes might be an overkill. And you could also
use a service locator if you feel more
comfortable with it. So let’s go back to– go through a concrete example. Let’s say we have a UI
that shows a user profile, and we have the
data sources which– we save it to database, we also
can get it from the network. How do we connect
these two things? Well, we said we first
need a user repository. User repository knows it
should check the database. It’s not there,
make a web request. Or meanwhile, also try
to run the database. It doesn’t matter
how it does it, but it knows how to
create a LiveData of a user or an
observable, doesn’t matter. And then we need the
ViewModel, right, because the data for the
UI lives in the ViewModel. So we create this
ProfileViewModel, which talks to the repository
to get this information. And then the actual
fragment gets the data from the view model so that
if the fragment comes back, the LiveData will be there
in the ProfileViewModel. But if the fragment
disappears completely, we will get rid
of the ViewModel, and the data can be
garbage collected. Now, all this
abstraction we made, if you notice, every single
component only talks to the one right below it, which is–
helps to scale your application. It also has a
great side benefit, which is called testing. You’re testing, right? So let’s say you
want to test your UI. Now, people say UI
testing is hard. UI testing is–
yes, it’s harder. But it’s usually hard because
you put all of your code into that activity. Now, we said, put most
of it into the ViewModel, and you know that UI only
talks to the ViewModel, so you can get rid
of the other two. You only need to create a fake
ViewModel to test your UI. Testing your UI become super,
super easy with Espresso. And we have a
sample app on GitHub that you can check
out with [INAUDIBLE]. And the same thing as
well as for ViewModels. If you want to
test the ViewModel, you know it’s only talks
to the repositories. You replace it with a mock
respository, and it works. And you can even
test your ViewModels on your host machine, on JVM. And last but not
least, you can test the respository the same way. You just mock the data sources. You can easily test your
repositories as JUnit test. Now, I know this has been
a lot of information. We have two sessions tomorrow,
and also documentation. But now I want to call
our product manager lUKAS to talk about what to do next. [APPLAUSE] LUKAS BERGSTROM:
Like Yigit said, we just covered a lot of ground. And actually, we glossed
over a lot of detail while we did that. But luckily, you don’t
have to remember everything that you just heard. We have a lot of material
for you to check out at developer.android.com/arch. And that link should start
working in 21 minutes. We wanted to give
you guys a chance to kind of blog and tweet
about this before anybody else. So that’s why we held it back. So yeah, we made having
good documentation and samples a priority from
the beginning of this project, since providing good guidance is
really one of the major goals. So you’re going to find
in-depth documentation that’s written from the perspective
of an app developer. You’re going to find really
meaty sample apps that show how to build a real app. And just as an example of
how much work went into this, we have a GitHub
browser sample app that probably has better test
coverage than many real world apps, written by that guy. And of course, we have the
guide to app architecture, which internally, we called the
Opinionated Guide for a while. And we think that
label still applies. But even if you’re not
planning to use our recommended architecture, we think people
should check out the guide. It has principles that we think
apply to all apps on Android. And you’re probably asking
yourself, do I not– what’s the impact of
this going to be on me? Am I going to have to change the
way that I’m doing everything? You know, if you’re
starting a new project, or if you have an
existing app, but you want to improve the
core architecture, then yeah, we recommend
taking a look at this stuff. It’s still preview. We won’t be hitting
1.0 for a few months, but we think it’s definitely
ready for you guys to check out, and
use in projects. But if you’re happy
with what you have, you don’t need to
rewrite your app. So in the spirit of be
together, not the same, we’re not dictating what
everyone has to use. If you’re happy with your app
architecture, you can keep it. If you’re happy with
your existing ORM, you don’t have to use Room. Architecture components are
designed to work well together, but they do work
perfectly fine standalone. And mixing and matching
applies not only to architecture components,
but also third party libraries. So– I’m waiting for
this slide to come up. So yeah, so you can
use what you have, and to start to integrate
architecture components where they make sense. So for example, if you’re
happy with Rx Java, but you really like the
Lifecycle aware component stuff that Yigit just showed, so that
you have these self-sufficient components, you can use
LiveData together with Rx Java. So you can get all the
power of Rx Java operators, and now it’s Lifecycle safe. So kind of the best
of both worlds. And we’ve got additional
integrations to come. We’re definitely looking at
a lot of stuff internally that would be nice if
it were self-sufficient and Lifecycle aware. And if you’re a
library developer, we really recommend
checking out Lifecycles and LifecycleObserver
because we think there is a really bright
future, and a lot of potential in making libraries and
components that are Lifecycle aware by default.
But before you go do that, we have a lot more
for you at I/O this year. We have two more talks,
one on Lifecycles that’s even more in-depth than
what we just showed tomorrow morning. We have another one on
Room and Persistence, and going a little
bit beyond Room starting at 12:30 tomorrow. And we’ll have people who are
well-versed in architecture components in the
sandbox for all of I/O. And we also have codelabs,
which we’re pretty happy with. And there’s more to come. So we think we’ve just
scratched the surface of ways that we can improve the
experience of using Android Frameworks, and we’re looking
at applying this approach in other areas as well. So some things
already in the works. And we’re also interested in
hearing from you on what else you’d like to see. So come by, talk to us, tell us
what you like, what you don’t. And stay tuned, because we’re
really excited about the future of Android development. Thank you. [APPLAUSE]

76 thoughts on “Architecture Components – Introduction (Google I/O ’17)

  • Android Architecture Components samples
    https://github.com/googlesamples/android-architecture-components

  • Android Architecture Components
    https://developer.android.com/topic/libraries/architecture/index.html

  • The Lifecycle APIs will remove a lot of unplaced code! Thank you for making this a reality

  • Great work guys! Nice to have first party support for MVVM and the likes. That newton-mars-rover analogy was very good. Looking forward to more such help for real world development.

  • Maybe one day reactive programming will be recognized by Google as a viable way to architect apps – a la RXJava.

  • if a viewmodel implementation needs to extend a base ViewModel class, how does it work with databinding? I assume we need to implement the data binding Observable interface? Alternatively is there an interface we could implement for a ViewModel instead? This could be done quite easily with Kotlin delegation.

  • Great work guys!! Nice to see there is finally a way to hold on to my pressures data and to monitor beter my observers and singletons.

  • This is great! And the fact that it's completely decoupled of the rest of the support libraries (as it is its own package) makes it even better.

  • Notice how the speaker keeps mentioning Retrofit, but doesn't mention Volley. I think Volley is no longer being pushed by Google.

  • This seems great, but what about the architecture for anything but simple CRUD apps? This talk, and the corresponding guide, seems mostly focused on apps which are just frontends for some webservice, not apps that have some sort of local processing. The app i'm currently working on doesn't have a database, because it doesn't need to store data. Aren't those considered part of the core of android anymore?

  • Is Room going to work with SQLCipher library? Will the new tools such as LiveData or ViewModel be available in the support library? I am going to start a new project very soon so this would be extremely beneficial.

  • Correct me if I am wrong, but after reading the Guide to App Architecture I have a feeling that:
    1. MVC pattern is being introduced as the (finally) correct one. But I remember some Google guru article that Android intentionally doesn't enforce any design pattern. What did I miss?
    2. Value observation is attempted to be introduced just as in the 'a**le' environment.
    3. The Android intrinsic — re-launching not only UI but the whole activity as well just because the user has changed UI (ie rotated the device) — is now to be dismissed under the layers of helper framework. Just like the 'a**le'.
    4. The Guide is nice and has a lot of great ideas how to make our apps great (again?), but why so late?
    I have come to like Android through these years, but this looks SO odd. But I may be wrong, and will be grateful for guidance.

  • I don't know, at a first glance lifecycle framework looks great, but isn't it just an official boilerplate for dealing with a bad architectural decision which are Activity and Fragment lifecycles? I mean, it's nice to see that Google finally decided how to do it in the right way, but why not try to improve the idea of lifecycle in its core so developers won't have to deal with all this stuff in the first place?

  • This architecture is pretty much similar to MVP, Glad you guys have provided official support It could be a fun 🙂 <3 for Google

  • Android Architecture Components Codelabs:
    https://codelabs.developers.google.com/codelabs/android-lifecycles/
    https://codelabs.developers.google.com/codelabs/android-persistence/

  • Ohh boy! Now I want to right another app ASAP. Thank you guys at Google (Yigit, Chet, Romane etc). Keep rocking!!

  • About 10:14, can anyone please explain to me why the myLocationListener.start() would be called after onStop? It checks the user settings on the onStart, and that's it… It shouldn't start after it.
    Or do they mean that the check of user settings is on another thread? But if so, why would anyone do such a thing…

  • Android finally catching up with java ee or spring it is really funny that took them to do it all that time 🙂 the OS design beneath it must be really shitty . If my observation is right at io18 we will going to see that Architecture Components has a new feature called composite views for modular view design just like in java ee

  • If I want to make a http request and return a LiveData, do I have to change to worker thread myself. Does LiveData has smt like subcribeOn method of Rxjava ?

  • In this talk (15:49) it's said sth which I do not understand. It's something like "when you use a LocationManager singleton in Activity it will cause memory leak".

    Can you explain how that LocationManager singleton causes a leak?

    I asked also here https://stackoverflow.com/questions/44456949/why-using-a-locationmanager-singleton-in-android-activity-is-bad.

  • Not really excited. People have been doing DIY MVP for years now. Why would anyone need another wheel?

  • There is no error & exception handling on these examples, is this ok? I think these problems could be addressed with proper error handling and exception catching or throwing.

  • Those people are not clapping loud enough for getting rid of the Contract class for SQLiteOpenHelper. They're also not clapping loud enough for the new viewModel class. Are these people even alive?

  • https://stackoverflow.com/questions/44456949/why-using-a-locationmanager-singleton-in-android-activity-is-bad

  • I created some samples to practice Kotlin and Android Architecture Components.
    https://github.com/erikcaffrey/Android-Architecture-Components-Kotlin or LiveData + Data Binding
    https://github.com/erikcaffrey/LiveData-DataBinding-Kotlin

  • Really? Another ORM? Java still lives in the past… why doesn't Google just copy LINQ from C# and be done with it? I don't get it. And why not just embrace RxJava? The Rx paradigm is well understood at this time

  • shouldn't this have been done the very first time, kind of seems like the obvious way to go about it.

  • "This is very confusing! This is so sad!" he says about ContentProviders & SQLite. People laughed at me when I said that years ago. What took so long for Google to admit it and let the rest of us repeat it without being laughed at?

Leave a Reply

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