Android Jetpack: how to smartly use Fragments in your UI (Google I/O '18)

[Music] hello everyone good morning and welcome to fragments in an architecture components world so over time there fragment api's have kind of evolved and as of the release of architecture components a lot of people have been asking us 

questions like sir how do all these things fit together so hopefully we'll be

able to answer some of those questions today but first just a little bit of history like the fragment api's go back to 2010 was when they were first initially written 2011 when they hit a little bit more widespread availability and really it kind of comes down to the idea that at the very beginning everybody just kind of started with the activity when you're writing an Android app it was kind of your main method with a life cycle it's the entry point to your application from the system the launcher will launch your activity you get all the oncreate on start resume etc events that you all know and love it'll create views for you it creates the window let gives you a place to inflate your view hierarchy where you do most of your UI work it binds the view content from your app state or at least this is where people tended to do it keep in mind that this was fairly early on in androids public lifecycle here everybody kind of had this habit of piling everything into one activity because apps were a lot more simple than they are today and of course you listen to UI events and update that app state from there as well so there are so many incoming events it really kind of became this plumbing exercise to try to break it up yourself so people ended up with these very monolithic activities and then something else happened to Android tablets kind of became a thing so we kind of thought you know how do you make a tablet UI well you take one phone UI you take another phone UI and you smack them together and you have a tablet UI right I mean what could go wrong so we needed to answer this question of how do I stick to phone you eyes together and make sure that it still works on a phone and fragments were kind of our answer to this question so as an example here this approach actually worked pretty well for some applications Gmail is a great example so if you take a look here you have the list of conversations to your current conversation that you're taking a look at and there's not a whole lot of difference here between the the phone version that you drill into versus something that you can show side by side in the two pane UI so fragments were really designed to make sure that you could do one thing and that was to allow splitting up these huge activity classes this was something that again we were seeing the pain that developers were feeling that their activity classes were getting really big and hard to manage so we wanted to see could we allow for you to decouple some of the various things that your activity classes are doing to sort of relieve a little bit of that pressure so that means that anything a fragment can do or anything an activity can do a fragment had to be able to do too and that guided a whole lot of the API design from the beginning so that meant that you needed to have lifecycle events that needed that meant that you needed to be able to manage a view hierarchy it meant that you needed to be able to deal with saved instance state so packaging everything up into a bundle or parcel bowls so that if your application got killed in the background you could restore from that in a clean way and other things as well like non configuration instance object passing and that's always kind of a mouthful but I mean this is kind of the way that you can pass any old object back and forth across a configuration change that doesn't actually kill your process back stacks were another really big one because suddenly if you were dealing with a single activity where you were navigating between fragments we wanted to make sure that we preserved that same back stack behavior that you're used to from just calling start activity from spring to screen so along the way we asked question can we fix some other api's that were really kind of a pain in the neck in Android to use on retained on configuration instance again kind of a mouthful this method kind of had some problems because you've only got one object that you could pass from activity instance to activity instance we didn't give you any easy or standardized way to multiplex diff objects together so for example if you were composing multiple libraries we didn't give you a whole lot of help this was all boilerplate that you had to write yourself activity show dialog does anybody remember this a few people okay please forget it immediately please please forget it yeah so this was essentially a way to get the activity itself to sort of do something that we knew was was missing and kind of a pain in the neck this allowed you to make the activity on the other side after a configuration change the new instance of your activity reshow what is semantically the same dialogue we also had this thing local activity manager tab host does anybody remember this one wow that is a lot more hands than I thought I would see so some of you might remember this from for example the original dialer and contacts app back in kind of the Android 2.

0 days and as you've swapped between tabs between the the normal number pad and your contact list or call log etc those were actually separate activities showing within a smaller window within an activity this idea of nesting activities was something that we started offering very early it had a lot of other issues though activities made a whole lot of promises that local activity manager had a lot of trouble trying to uphold so we wanted to try and tighten that interface a little bit better for something composable like fragments that would be able to do the same thing but with a little bit more expected behavior right so this whole idea of being able to break up your activity and make it into kind of composable pieces you know we have this giant monoliths of an activity and you know there's other methods of kind of factoring it out into different pieces but for fragments basically approach was you move that loosely related code right those view and all of the state around that view into a separate fragment and you basically just keep doing this until you've kind of segmented out your activity into something that looks slightly more reasonable right you may have a couple of fragments in here that kind of have their own specific requirements and their own specific UI and your activity just becomes more of a show for this but soon after we started getting into this and when it came up to around jellybean people were like but this isn't enough like what if one of my fragments has a viewpager in it that also has fragments as each one of its pages so we get into this alright well now let's break up the fragments into smaller pieces so of course you know the only way well if fragments aren't enough then you just add more fragments in this case child fragments became a thing so now each one of these fragments could then be broken up into smaller pieces so this allowed us to kind of again kind of D couple things and we built a lot of code around trying to make this nested state work really well to varying levels of degree of success but it's gotten a lot better over time so with these things in mind every one of those fragments whether it's a small thing just managing a view or if it's a retained instance fragment every single one of these fragments give you life high cycle hooks every single one of them has back stack management associated with them every single one of them has a retained object that I can do across configuration changes and all of them are stored stateful e in your fragment manager that means that the existence of that fragment is actually part of the state of your app so when your app dies and comes back that existence in the fragment manager is actually a really important part that at least from fragments perspective that we're going to do on your behalf and of course they all have their own ability to have a view subtree so that piece of your UI that they manage themselves and of course we also allow things like fragments being inflatable and put right into your XML files and be able to reuse them across multiple layouts and again this is also kind of hooking into these same processes but the biggest issue we found is that all these fragments do all of these things at once whether you want them to or not and most of the time you're only actually using one or two of these things and not the full 16 things that fragments do that you get as kind of a bundle of deal so that means that some of these things like the stateful restoration means you have a lot of patterns that look like this where you have to make sure that the fragment manager is in the right state so in this case we're actually checking well alright is there no saved instance state ie are we in a fresh run of this activity and oh now I need to add my fragment to my layout so if you've ever gotten this approach where you have one fragment over another one yeah this is this kind of state full restoration actually being something that was a useful bit but at the same point like maybe not exactly what you were expecting or something that you even wanted in some cases but for fragments you kind of got all of them together in a package deal but last year we kind of took a more holistic approach to how we do api's and this really kind of started with a lot of the work we did on architecture components so all of the architecture components have really tried to focus in on doing one thing well rather than being kind of the kitchen sink kind of approach so for example lifecycle observers the ability to have life cycle and that onresume on start as kind of a piece that is completely independent from other things something that you can register just if you care about life cycle similarly for view model we created a new primitive a new object specifically for that kind of retained instance state across configuration changes and of course this year just yesterday we announced a new navigation architecture component kind of working at the a much higher level architecture on how you bill your UI and put these things together and really trying to tackle just the specific problem of how do you move from one screen to the next screen so all these things were kind of really focused on doing one thing well and we're trying to bring a lot of that to fragments but that means that you know we kind of have a lot of legacy to go along with that that's right so part of this is that fragments were really designed around this idea of very loose dependencies and loose guarantees about some of the interaction between them so another kind of quiz for the audience how many of you know the answer to this question does a child fragments oncreate method run before or after its parents oncreate method how many of you are confident that you know the answer not a whole lot I'm gonna give you no idea about no how many of you thought you knew the answer before I asked the question and then you started questioning yourself yeah okay I'll admit that sometimes I have to double-check this as well because the answer really kind of depends on whether the parent is an activity or if the parents of fragment what version are you running on are you talking about Android app dot fragments or the support library fragments because the answer has been different over time we've changed this around and if you were trying to design a fragment that worked across all versions of Android that was writing to the framework fragments you had to deal with these rules kind of changing out from under you a little bit you couldn't count on anything so one of the things that we allowed for here with lifecycle observers is that we really wanted to give a very strict ordering of the callbacks you have a strict lastin first-out callback ordering for all lifecycle observers in any given lifecycle this is important because it means that you can set up dependencies between lifecycle observers and use lifecycle observers as the implementation details of a particular activity instance or fragment instance as the case may be you can make sure to maintain guarantees between certain lifecycle events so that any other lifecycle observers that other libraries you may be using can take advantage of those guarantees that you've configured lifecycle observers are created by you we don't try to recreate them via reflection which means that you can use any sort of creation pattern that you may find useful within your app so this seems like a really small thing but it was a big piece of feedback that we got with fragments the implication of that though is that you no longer get stateful restoration by the system now again in some cases this is exactly what you want you want to make sure that you have a single control flow path as you're configuring your lifecycle observers you don't want to be checking hey is my instant state going to bring this back for me I don't want to end up with two of these things so on and so forth right so one of these really common patterns that we saw a lot of app developers using is actually a headless fragment a fragment without a UI that was used basically only to receive on start on stop life cycle events so for a lot of these kind of approaches lifecycle observers are going to give you the same kind of API service but with a lot smaller kind of API that you don't actually need all of the things of fragment so what does this actually look like you might have just a simple life cycle observer that does analytics calls and your analytics library might want on start on stop of a particular lifecycle so the thing here is that this is an independent piece from fragments from activities now that has a couple of super important things in that one you can test it independently you don't have to spin up the whole world just to test this piece you can test it in isolation also because you can create this observer you can use whatever methods you want if you want to use an dependency injection kind of model and inject in your dependencies like that is really easy to do in this model rather than trying to do it in the scope of an activity or fragment or doing that kind of thing so this gives you a lot more power to kind of split out this into a composable piece so if you're building a library you can just use this same lifecycle observer across all of your fragments or all of your activities and not have to duplicate that data or worry about like okay well what state is my instance data and you can just always say add the observer and we're done there's no more no more work you need to do here so this offers a lot simpler alternative for this specific use case we've got some glowing slides to get there okay so retained instance fragments we're really designed to outlive an activity these were basically just a setter on a fragment to say hey retain my instance state across across configuration changes this was a pretty useful thing because it meant that you could save handles to expensive data or operations if you start some sort of query that might take a little bit to complete you don't want to restart that just because somebody rotated the screen or something got resized it meant that you could reconnect to these same operations after that configuration change but really please don't do UI during this this was another one of those kind of headache pain point sorts of things fragments do everything all at once but these were two things that just really did not taste great together the reasoning for this is of course that views hold on to the context that created them well what context do you use to create views most of the time well it ends up being the activity you don't want to hold on to a reference to an old activity after a configuration change ended up using the same views now technically it's possible to do this right you can go ahead and drop all your references in ondestroy view recreate the view after after you come around the other side this was way too difficult to get right all the time just because references to these views end up leaking out and getting everywhere no matter what you try to do so this was something that was it was really just kind of a foot gun waiting – waiting to hurt people but of course in the architecture component world there's a different solution for this retained instance pattern and that comes in the model of view models so this was kind of a brand new class and to be honest the class doesn't really do a whole lot it's how it connects to the overall system so instead of being again part of the fragment api's this is a more general-purpose thing something that you can attach to any activity or any fragment or any view model store owner if you're building your own framework and the main thing that's different here just kind of like the lifecycle observers is that we are not the owner of creating those objects so by default we provide a factory that just creates a new instance or creates a new instance and attaches your application context to it but at the same point this is a super powerful hook for again kind of adding in those extra dependencies so if you're using dependency injection like again you have kind of the hooks you need to hook into the view model creation and pass those in just as a constructor parameter right there really doesn't need to be a more complicated structure than that so but you get into the same problem of like okay well how do I connect my UI and the other piece of the puzzle here is a different architecture component called live data and live data is kind of all about a lifecycle aware observer so in this model in this world your view model is the one who's storing the data right and it's the live data that it has that it can then pass to the activity or fragment as they get created and recreated and that fragment or activity can just observe the live data that the view model owns so this model kind of separates things out where instead of it being the view model that needs to hold on to a reference to views the activity can then pull the information out of the view model so I think for a lot of use cases where you're using a retained in some state specifically to kind of store this expensive data and do that kind of work view models offer really good alternative to retained instance fragments so what's a super simple one look like well in this case we're going to use an Android view model so here we get a reference to your application your application context so this is really useful if you're doing things like a service locator kind of pattern but the important thing here is that the view model stores an instance of a live data in this case I live data that has a list of our fancy renamed expensive data class now normally you'd put this in line but slides are hard so here we're using it and we're getting our data from a room database a simple or database but you can really get this data from anywhere or set up kind of the correct lifecycle events here so that your live data can kind of get into the right State but that means that your actual fragments or activities don't need to know where this data came from right it's encapsulated in the view model and again we're in the same thing where we can now test this view model in isolation we don't need to create activities we don't need to create fragments to get to this same view model we can just use them in isolation and make sure that all of the work we need here to get our expensive data and make sure that it's in the right State can all be done kind of separate from the actual UI pieces of the framework all right so everybody's favorite topic when it comes to the fragment API is fragment transactions because this is a statement that said by you know pretty much no one ever fragment transactions are asynchronous by default if you call commit on a fragment transaction then that ends up getting posted for later and it'll occur kind of on the next normal Handler pulse of your main thread or if another life cycle event is coming up we'll go ahead and execute all the pending transactions bring it to a consistent state before we move to that next state now this actually has a few benefits to it believe it or not for as much as everybody gets kind of frustrated about it and the biggest one is that you don't have any reentrant fragment operations this means that if you end up manipulating fragments within say the oncreate of another fragment then you don't start getting into a state where you have a half initialized fragment while you're waiting to bring another fragment up to speed now this is a source of countless bugs I think that it was even just earlier this week last week that we were helping developer troubleshoot some other reentrant behavior bugs that was coming from view callbacks for example and this is the sort of thing that is can be really really subtle and the asynchronous fragment transactions sidestep all of it and that was kind of convenient the drawbacks are of course that the observed state at any given point in time doesn't actually reflect any of the queued transactions so this is a huge problem this basically means that if one piece of your code submits a fragment transaction another piece of your code tries to read something out of state that that fragment would have set up for you whether that's another view hierarchy that would have gotten attached to sort of a sub hierarchy of your UI or whether that's just some data about a pending operation say for one of these retained instance fragments this essentially means that you can't trust anything about the current state of the app it means that you can have various data races just within the normal main thread handler of your application we've even seen people run into the issues of sort of the the layered fragments on top of one another because of this issue because they were checking the fragment manager to see hey what is my current UI pain for example that's currently there it said oh look nothing I don't have anything to do let me go ahead and make a new fragment transaction and stick something there but there was already something in flight so this was something that was really kind of a pain in the neck and everybody loved when the commit now API was added because it lets you do something right immediately as long as you promise that you weren't gonna do anything with your current fragment manager as part of that transaction but we kind of get to this point where okay now we have all these fragment transaction code in your app and very subtle changes that you may not pick up in a simple CL all of a sudden are changing the whole behavior of your app and we really took a look at this and we said well like should you really have to be writing all of these fragment transactions by hand like for so many of the use cases we can do a little bit better here we can do a lot better here especially for the really common cases so we built navigation brand new architecture component that's really kind of focused on that screen to screen transitions between fragments or other UI pieces because we really want to make it work well with fragments fragments are a really great way of getting access to lifecycle observers and view models and also you know being an owner of a view and those are really kind of the main pieces you need when you're trying to build a good Android app at the same point we realize there's a lot of things that fragments do that we don't really want you to have to deal with yourself so one of the things with navigation that we really focused on was actually being able to take ownership of the back stack make sure that the navigation component can actually handle that back stack for you whether using fragments are using something else the ownership of that backs that kind of lace with navigation that gives us a lot more flexibility and a lot more ability to you know be a little bit more prescriptive and a little bit more opinionated on what is a good thing to do and what's a not-so-great thing to do and kind of give you a lot of the same power of fragment transactions without actually having to touch one with your our hands because again we're trying to make things so that you know you have all of the power without necessarily the headache and the problems that run across some of the things that Adam pointed out so we're gonna be talking in detail about navigation tomorrow morning at 8:30 I know you're all early risers but I wanted to give you a little bit of a preview kind of how simple this could be so we actually offer a helper method where if you want to click a button and do a full-screen transition to another fragment we have a create navigate onclicklistener that literally just does that just that all you need to do is pass in the ID of one of those destinations that you've set up in navigation now this looks a little bit magical so what is this actually doing under the covers well really what it's doing is it's using this nav controller object and one of the things that I find super useful about navigation is you can actually find that nav controller from any view or any fragment that's been created by navigation so here we're using a column extension which makes this a lot easier if you're in the Javal and it's just a static method but here we can find from any view we're going to say find nav controller and get an instance of our nav controller and then just call navigate and this navigate call knows how to do fragment transactions so our nav controller in this case is set up with a fragment navigator our own class that knows all about the correct behavior of doing fragment transactions and how to do all of that work for you so that from your codes perspective you can just call navigate and we'll do the right thing for you so obviously there's a lot more here like if you want to pass arguments like you can do a bundle approach we also have a lot more things around that specific case that we'll be talking about tomorrow as well as well as setting things like separate animations and other objects in here so you have a lot of the same power but you can also make it really easy to use and move a lot of the code that used to be a fragment transaction that you'd have to make really sure that you got right into something that navigation can understand and helpless so Adam we've talked a lot of things about why not fragments but this is kind of a fragment talk right so what why that's why everyone's here yeah so why fragments its 2018 it is 2018 so what what are fragments still good for after we've sort of carved off some of these other extension points so before we talk about that I think it's kind of important to go into a little bit about the package layering involved in the android framework specifically in bridgit versus android app now Android dot widget is really kind of designed to hold all the mechanism for your UI that means that this is all the stuff that shows state to the user and things that reports user interaction events back to other higher-level portions of your app and really that's it anything that's in the widget package is really meant to only do these two things whereas Android app which is where fragments live activities live so on and so forth that's where your policy goes this is what defines what state to bind to widgets this is what defines how you should respond to those user interaction events and how to issue changes to your data model anything kind of at that layer or above no matter how you may factor it this is kind of how it's how it breaks down so this also brings us to this idea of inflatable components which is something that comes up quite a bit since you can inflate a fragment from a layout people found out really quickly that you can use a fragment to compose some of your views together and create basically like a custom view but with a fragment and really some of this kind of comes in because people start asking you know just if this view had a lifecycle I could as something but really you kind of want to use that as a stopping point and just kind of ask yourself like what is it about this particular view remember mechanism only that needs a lifecycle if you should really only be showing the that they're given or publishing user interaction events if the user clicks touches or performs any other action on the views themselves none of these things need life cycle events to accomplish that goal so you should really kind of watch out and figure out okay do you need some sort of policy layer that sits above that this is where fragments are really useful because you can compose them of higher level controls it means that they can be self-sufficient they have their own life cycle they know how to hook into some of these things they need it means that inflated attributes can actually become fragment arguments so you can make these things super self-sufficient and implement cross-cutting UI policies that you don't have to worry about in terms of like the overarching top level parent context this ends up being really useful for things like I mean even just something as simple as adds something where you really do need to control for a lifecycle about when a user comes and goes perform a request out to the network to fetch the content that you're going to show but really you don't want that code getting all over throughout the rest of your application logic you can use this for other sorts of like independent info cards things that are again fully self-contained and the parent doesn't actually need to be involved in any of the data routing from your central repository or whatever other sort of model you're using under the hood in order to get that on screen and get the user interacting with it so one example of using the fragment arguments for this is on screen here this is the sort of thing that could probably benefit from some extensions or helpers but overall it's it's not too bad if you define a style able to go ahead and inflate some of those arguments just assign the values to the bundle set it there and then you can route all of this logic through your normal fragment argument handling that appears throughout the rest of your fragment implementation so one of the other use cases that we found really useful for using fragments is this kind of app screen kind of model so where a fragment is taking the vast majority of the screen it's really the main content of your app and this is really kind of where navigation and really kind of takes away a lot of the rough edges of fragments so you're just left with the architecture component hooks and a view so in this model it's a lot easier to move towards a single activity out if you've listened to Chet yesterday and this is kind of our recommendation going forward to kind of use activities just as an entry point into your app and then your content the actual things that the UI the pieces that developer or users actually work with are the fragments of your app right the actual content is in fragments so with this model the only thing the activity needs to do is handle kind of common app chrome so if you're using an action bar still or if you're using like bottom nav or a side nav these would be good things that the activity can manage but the rest of it can be decoupled destinations decoupled screens all of these fragments can be much more independent from one another rather than being tightly coupled together so this allows us to kind of move a lot of things that normally you'd have to deal with manually into a system that we can help you out a lot more on so for navigation for example we're going to give you the hooks that you need to set up the transitions and animations needed to transition between these screens and it's something that can be done in navigation rather than something you have to do by hand of course like these aren't mutually exclusive right you can still add a fragment to your layout or have nested fragments underneath these things so it's not an all-or-nothing kind of an approach it's just one method that yes this larger kind of content based fragment is still a really good way of kind of bridging the gap between the Android app world and the widget world another use case that is still super useful is around dialog fragment again we talked about kind of the active he showed aiya log I hope everyone forgot that by now like I said but dialog fragment is really kind of the same approach where instead of it being something that you need to manage and make sure is visible or not visible it really kind of helps encapsulate the interaction between a floating UI like if you have a really important question to ask the user a dialog is probably a useful case in some manner but it's also something that we've started to see a lot more in Android P for instance the biometric prompt for fingerprint is now something that is in a dialog kind of model so this is actually something that we found really useful and part of it is that we can leverage some of that instant state restoration that you get for free as part of fragments with your dialogue this means that you've asked a really important question otherwise why would you show a dialog and interrupt the user but you really don't want that to disappear when you resize your screen on a pixel book or rotate your device on your phone it's a really important question we want to make sure that we do some of this instant state restoration for you at the same point like dialogues aren't just a floating UI right there's also bottom sheets and bottom sheet dialog fragment specifically built around kind of having different kinds of floating you eyes you eyes that live above your main content without necessarily being just the lagged in the background kind of traditional dialog of your so we're really trying to get to this point where yes using a dialog fragment is great if you have this UI that you really don't want to lose right it's really important for the user you know obviously for things that the user could use could lose it's probably not a dialog that you want to use it's probably a snack bar or another approach here this is my favorite part about dialogue forever there's literally nothing more you need to do you call show or show now for the synchronous method and that's it very much kind of this model where we're going to do the fragment transactions for you again like we don't want to be in a model where you have to do a lot of complicated work yourself for a dialogue fragment you can literally just call show and it'll do the right thing and it'll get you back into the right state all right so one of the other things that people tend to use fragments for quite a bit is managing options menus and specifically merging some menus into some common into a common tool bar into an action bar that's global to your activity so fragments support options menus because activities support options menus this kind of calls back to that initial design goal where fragments had to be able to do anything that an activity could do and the most common use case in this today is for calling set support action bar for your tool bar which then sort of binds whatever your current context is to to a particular tool bar within your UI now this is really great if you have some fixed common Chrome's so in the navigation world if your toolbar never changes between screens then this is really handy because the this means that you can populate that with whatever actions are relevant for what's in your main content fragment pager adapter is another really great one that people use this for quite a bit if the actions change across pages then all of this is just kind of handled for you the system takes care of it now the alternative to this is that you can go ahead and directly manage the menus as toolbar view data so most of the time today your UIs are such that the toolbar or other sort of menu management is really kind of part of the content I mean this was something that you saw back in a lot of hollow UI is where the action bar was always fixed common chrome but now you have these collapsing app bar layouts and things that are much more sophisticated to the point we're doing this sort of global wire up is almost jumping through hoops that you don't really need so don't make it more complicated than it needs to be if you don't have common chrome for this then directly managing some of the toolbars menus as view data is as simple as this like it's a couple lines of code there's not a whole lot to it you inflate your menu you attach a click listener and you can keep all of this a little bit more self-contained rather than having this leak out into the whole activity options menu at that point so one of the other things that we get asked a lot is about testing fragments testing fragments is a whole lot easier than testing activities you don't have to spin up the entirety of the world an entire new activity with sort of the back and forth in an instrumentation test to the activity manager to make this work the nice part about this is that from quite a few years ago we've had this glass fragment controller that is able to drive the life cycle so you can go ahead and you can create just a test fragment manager test fragment controller that can test those larger fragment components in isolation away from everything else that might be happening in the activity manager we use this pretty extensively for the existing support library tests ourselves now we make this possible but truth be told this is really not the best interface for doing it it ends up looking a little bit like this or you could go through some of the support library tests in AOSP and see kind of the example of some of the utility methods that we've set up for this we should really probably wrap this in some better move to state type of method this is one of those cases where we've fallen into a trap ourselves of some things possible it's maybe not great the rest is kind of left as an exercise to the reader and we kind of just need to do better on this part yeah so one of the other pieces that kind of came alongside of fragments more from a convenience method than anything else were loaders a kind of precursor to a lot of what we've done in architecture components on doing retained infant States and one of the things we've done recently is actually tried to decouple them from fragments so how do we actually do this well instead of being their own special thing we actually rebuilt them on a lot of the architecture right using these new primitives we have of live data and view model to kind of make these a totally independent thing so now you can actually use loaders in any lifecycle owner if you model store owner class so activity fragment if you're building your own kind of thing it works equally well in all of those cases so what does this mean well it really just means that you have the same loader you always do but instead of calling get support fragment or loader manager you can just call get instance and we'll do all the hookup for you we know that you're in a lifecycle observer so we know how to hook all that stuff up for you and you really were able to kind of cut out a lot of the stuff cut out a lot of the custom behavior here so that you know we can kind of rely on these new things to give you stronger guarantees around lifecycle so we've talked a lot about fragments and we've talked a lot about fragments in the past and we've talked about fragments in 2018 but there's another question where are we going with fragments what do we still have to do so some of this is just coming down to building in those stronger guarantees trying to separate the desired behavior things that we've specifically set out to put in versus incidental behavior more behavior that has just been around for six years and it's not necessarily something that is a codified standard so we're trying to move towards more of a model where you can be very confident in exactly what's going to happen when you're using fragments another case is trying to do the same thing with that we did with loader manager in in re implementing some of these existing api's on top of these new primitives for example like being able to rewrite a lot of the internals of fragments so they're actually using lifecycle observers under the covers right so these kind of things allow us to kind of make sure that all of our components are on the same page and really doing the same thing so a few other things again trying to move towards a world where we have the correct set of signals and activity callbacks so that any interested component can be it that means that fragments are not a special snowflake anymore they're just another component another tool in your toolbox using the same composable hooks that you'd always have so really trying to play well with other components so that it's not an either/or it's a both that we can work together that you can use fragments alongside other components and it just works all right so options menus are of course one other thing that we still don't have a great answer for this in terms of how we want to decouple this I mean in a lot of ways I would like for options menus just kind of as a concept to be deprecated but for right now we still need to make sure that we meet all those same use cases for when you do have common chrome or for when you're paging through some different content next one maybe there we go okay so Android opt-out fragment manager some of you've noticed is now officially deprecated so no more of this kind of behavior changing out from under you having to design against different variants of it this works a whole lot better in the Android X packages and support library before it because this means that you no longer have to worry about all the bugs that were fixed over time it allows us to make larger changes to the behavior and API please send us your wish list for the things that you'd like to see us do for some of this too we are going to be over in the sandbox area right after this so please come say hello tell us what you'd like to see next and thank you very much for coming [Applause] [Music].


http://www.allads.co.in/user/profile/50324
https://www.anunturi-romania.net/user/profile/16490
http://beldanga.allads.co.in/user/profile/50327
http://bhubaneswar.allads.co.in/user/profile/50326
https://gumtreeads.com/user/profile/69680
http://kundrathur.allads.co.in/user/profile/50331
http://www.list-maine.com/craigslist/user/profile/37035
http://namchi.allads.co.in/user/profile/50329
http://new-delhi.allads.co.in/user/profile/50330
http://shillong.allads.co.in/user/profile/50431
http://tindwari.allads.co.in/user/profile/50335
https://wiki-trade.com/user/profile/19131
http://adolx.com/user/profile/30962
http://agahidan.ir/user/profile/26801
http://www.bom-negocio.com/user/profile/42940
https://doska.obyavka.by/user/profile/80616
http://www.ecbay.com/user/profile/28119
https://eu-bb.com/user/profile/59091
https://www.list-nh.com/craigslist/user/profile/31670
https://vadaszapro.eu/user/profile/37310
https://www.compraventagirona.com/user/profile/18900
https://www.filaliman.tl/user/profile/24341
https://www.haripita.lk/user/profile/25070
https://jevendsmaboite.ovh/user/profile/15505
http://www.militaryvids.com/user/u5tldcd187/
https://www.petads.com.au/user/profile/27717
http://petite-annonce.golf-colors.com/user/profile/20110
http://www.puppysaleindia.com/user/profile/13506
https://www.uksecondhand.co.uk/user/profile/29040
https://xtutti.com/user/profile/9956
https://www.acheterlouer.xyz/user/profile/37277
http://www.all-biz.com.ua/user/profile/12408
http://azurboard.com/user/profile/28851
https://www.bienvenidog.com/user/profile/13540
https://www.briquetri.com.br/user/profile/56065
https://bulk-sell.com/user/profile/19420
http://helpme.saturn.tj/?qa=user/k0zjpbu751
https://jioads.in/user/profile/12746
https://www.modellsalg.no/user/profile/24152
https://neozzle.com/user/profile/27137
http://realestatechandigarh.com/user/profile/28292
https://riauniaga.com/user/profile/34164
https://uncachu.com/user/profile/43233
https://vipfancynumbers.com/user/profile/15632
https://adguro.com/user/profile/32274
https://aholmi.hu/user/profile/131307
http://fundam.su/user/profile/34748
https://www.mes-petites-annonces-gratuites.net/user/profile/249805
https://sewalaku.com/user/profile/19378
https://www.sprzedawczyk.pl/user/profile/70176
https://unme.us/user/profile/12545
https://vanzatorul.com/user/profile/86744
https://1iklan.my/user/profile/28720
https://www.2dehandsnederland.nl/user/profile/45340
http://99globalads.com/user/profile/42026
http://board4me.com/user/profile/72998
https://eyetrade.ug/user/profile/25974
http://jarzani.ir/user/profile/25045
http://www.jharkhanddirectory.com/user/profile/19396
https://jumush.su/user/profile/9367
http://kritih.com/user/profile/30621
https://luga.sale/user/profile/34463
http://maavatam.com/user/profile/18160
http://polakker.pl/user/profile/13010
https://www.portalmarkets.com/user/profile/31901
http://www.sellytnow.com/user/profile/17443
http://www.sulitbuys.com/user/profile/22468
http://us-free-ad.com/user/profile/15315
https://vendobarato.com/user/profile/50678
https://www.wazzy.com/user/profile/37257
http://weedbler.com/user/profile/27220
https://affariat.com/user/profile/42233
https://buysellnow.co.uk/user/profile/26026
https://www.globiad.com/user/profile/3281
http://www.gumtree.in/user/profile/27406
https://market.co.ua/user/profile/11530
https://rus-ads.com/user/profile/37285
http://www.serviocasion.com/user/profile/14560
https://sta-caravans.nl/user/profile/10448
http://supermercadotecnologico.com/user/profile/9397
https://mycraigslist.org/user/profile/172449
https://vdo.com.ua/user/profile/24191
http://ventasdiversas.com/user/profile/70501
http://www.zeds.in/user/profile/12243
https://www.antalyaaquapark.com/user/profile/1655
http://www.buysell.com.pk/user/profile/42107
http://www.congoemploi.net/offres/user/profile/14147
http://www.groovyfreeads.com/user/profile/57197
https://ladipomarket.ng/user/profile/20756
https://www.naughtylist.com.au/user/profile/31168
http://numpangdagang.com/user/profile/11862
https://www.postyourfreeads.com/user/profile/16307
http://publitodi.com/user/profile/12639
https://vekslak.sk/user/profile/3082
https://www.viterboh.it/user/profile/11060
https://2buy4saleonline.com/user/profile/51108
http://a.bright.kz/user/profile/346747
https://aswaqmasr.net/user/profile/21296
https://bahriatrade.com/user/profile/13271
https://browsemycity.com/user/profile/33251
http://coffeecat.com.ua/user/profile/14214
http://www.conexionhiphop.com/user/z5kiupk704/
https://www.crownpageant.com/user/profile/157991
http://www.funkyfreeads.com/user/profile/57714
https://www.kayak-merkezleri.com/user/profile/5538
https://www.acheterlouer.xyz/user/profile/37303
http://www.billiardvideos.com/user/o2nqxgs344/
http://fajarjitu.com/user/profile/7245
https://www.lankaads.net/user/profile/27768
https://parduociau.lt/user/profile/7786
http://superniaga.com/user/profile/8544
https://toletworld.com/user/profile/1947
https://www.keralaplot.com/user/profile/8220
https://www.mallorca-basar.com/user/profile/18265
https://www.masaje.one/user/profile/7089
http://buzdubai.com/user/profile/84744
https://mycraigslist.org/user/profile/172486
http://schnappen.de/user/profile/11690
https://www.turkeycarrentalcompany.com/user/profile/7847
https://kirillovka.biz.ua/user/profile/21153
https://agyds.com/user/profile/10368
https://www.andrahandsverige.se/user/profile/7099
https://www.annonseragratis.xyz/user/profile/7036
https://anunturigratuiteonline.info/user/profile/4705
http://www.dachtube.pl/user/m8crxqt474/
https://labeltv-ghana.com/user/f7kwzqd747/
https://pathta.jp/user/profile/1156689
https://purbelibazar.com/user/profile/9668
https://razdal.com.ua/user/profile/14799
http://rc-advert.com.ua/user/profile/8013
https://sapphiremarket.online/user/profile/3370
http://sucatavirtual.com/anuncios/user/profile/7092
http://www.video.com.pk/user/a8fwwpw961/
https://www.2dehandsnederland.nl/user/profile/45365
https://gumtreeads.com/user/profile/69768
https://1iklan.my/user/profile/28744
https://gumtreeads.com/user/profile/69702
http://www.adsportal.in/user/profile/651428
https://www.24nova.com/user/profile/58379
http://board.puzzler.su/user/profile/21986
http://adipositas-verzeichnis.de/user/profile/43058
https://www.antalya-dolphinarium.com/user/profile/10128
http://englishtown.rackons.com/user/profile/90306
http://imolocal.com/user/profile/1895521
http://www.megafon.net/en/business-directory/user/profile/58050
https://www.pingofive.com/user/profile/140014
http://biologplace.com/user/profile/55629
http://www.buyselltrademyanmar.com/user/profile/117018
https://job-ofertas.info/job/user/profile/87063
http://www.leningradskaya.org/d/user/profile/12123
https://www.postonlineads.com/user/profile/47639
https://7emirate.com/user/profile/31055
https://belizeanuncio.com/user/profile/1309801
https://www.ivoirannonces.com/user/profile/442362
http://pueblo.tommyslist.org/user/profile/57958
https://www.dodajogloszenia.pl/user/profile/195850
https://www.immo-web.ro/user/profile/35429
https://ru.dorinza.com/user/profile/21195

Nhận xét

Bài đăng phổ biến