 mvc, mvp, mvvm and mv whatever. So I'm just going to talk about v here, views, nothing else. So Sake gave a very nice talk on how the layout administrator actually works in which you write XML layouts and everything just magically works. How many of you actually love working on XML layouts going back to your Java code finding some view by ID in half a dozen null checks and then setting the text on a view. I thought so. So for the past one year, we at Flipkart have been working on a library and I'm here to share with you. So in Flipkart, we call it Proteus. So what is Proteus? To summarize, it's basically meant to be a replacement to Android's XML layout inflator. What it will allow you to do is send layouts over the wire and inflate layouts at runtime. But the question is, why would you want to do it? What advantage does it bring? So the answer to that question is answer to another question. What do you want to do? So we at Flipkart want to provide the latest and greatest of our app to our customers, to all our customers, and therein lies the problem. Today the way we develop apps and publish them is fundamentally flawed. So let's see what happens today. Okay. One fine day your manager comes to you and says, can we change the color of the buy now button or probably increase the size of our images or maybe change the buy now button to a book now button for certain products or probably just add a subtitle. And you're going to say, sure, sure we can, but next month. So he's like, dude, it's like an arse job and we can do a deployment tomorrow. Well, one does not simply release an app for Android, but why is that? That eventually boils down to a release model. So traditionally you would actually batch up all your for a month, a monthly release cycle or a biweekly release cycle. Then you'll go ahead and touch features and you're going to test them. You're also going to test your old features for regression. Then if you guys are into a testing, you would actually implement every variant of the component and then bundle it into your APG, which will increase your app size also. So how are apps built? You guys already know this. You build an app, add all your cool features to it, test it out, and then you publish it to the place show. From there, the users have to download it and then install it on the phone. Okay. So what is an app? App is your business logic, which in this case is Java, your layouts, the XML layouts that you write and a bunch of assets like images, icons, et cetera. All of them bundled into APK. And it is this APK that is actually installed on the user's device. And this is the problem. This thing is installed. You cannot actually modify it. And in a country like becomes a problem because if your users want the latest features of your product, they will have to go back to the place show. Insta. Okay. Is it gone? So the users will actually have to go back to the place show and download and install the entire app again. And in India, it's a problem because you have network and the data is still costly. And if you have a sale coming up, like we do in Flipkart and you have a large chunk of your users on an older version of the app, which has lots of UI issues or which does not have that offer banner, you end up losing a lot. So now I'm going to move towards a certain use cases, which prompted prompted us to make produce in the first place. Okay. The product manager comes and says, let's AB test the color of the vinyl button. Okay. So if you can go ahead and be a little smart, you're going to save your color in some sort of a conflict, which you're going to fetch from the server. And then you can set it on the button, right? But you will still do it next month. Fair enough. What if you want to test two different layouts for your ads? In this case, you'll probably have two XML files and based on some configuration, you're going to switch between them. Okay. Next month, this will also increase the size of your app because now you'll have two XML files. But what if your product manager comes and tells you, let's AB test this against this. Obviously a previous strategy just went out of the window. There are too many changes here. The toolbar is missing. The image size is different. Even the way ratings and reviews are shown are different. The icons are different and the colors are different. Just can't do it to tell you the truth. These are not actually mocks. This is an actual AB test that we ran on Flipkart application without an app release. But how is that even possible? So that's what proteas did for us. Now my presentation is mostly going to be filled with demos. So I'm going to go head over to a demo now. Okay. So here is basically in my gradle file, I'm going to add proteas as a dependency. I'm going to sing the project. Now in my main activity, I have already written a fetch method, which actually fetches all the layouts and data just for simplicity. Up over there, I've also written another method called render. And inside that inside this render method, I'll just show you how layout inflation works with proteas. So in proteas, you use a layout builder and said it's basically equivalent to the layout inflator and you create a new instance of it. Now, just like you call layout inflator dot inflate and get a new instance of a view, you create a new instance of a proteas view and you call layout builder dot build. You pass in a couple of parameters called the container, the parent for the layout parameters, the layout data and styles. I'll come back to you data and styles later. Now the view that this build method has written is an actual native view. It's not a web view. It's no magic going on. It's a proper native component and you can add it back to the container. I'm going to build my app right now. My app is empty because if you see on the left side, the layout JSON is empty. I have not defined any layout at all. So I'm going to do a very small layout for you. Let's just call it a text view. Then I'm going to add a few layout parameters. I wish I could have typed faster. Okay. So I'm giving it a large text size so everyone can see it back there. I'm going to give a text called hello world. I'm going to save it and I've basically enabled the fab to actually pull the layout again and render it again. That's it. So you basically saw hello it now in protein. So what did you just see on a very high level? This is what Proteus looks like. It's a black box. It takes in a layout. Chucks out a native view. In addition, you can plug in your own custom views and attributes. And Proteus will also give you some cool cool call back back into your application. So you saw the layout, right? The one that I wrote, you would have noticed that I was writing in Jackson, but other than that they're pretty similar. The tag attribute is basically the type attribute in linear layout and the child nodes are basically the children array. Everything else is pretty much the same layout width is layout width layout height is layout height margin left is margin left. Not much difference, but why do we even go with Jason? Right? And I just send the XML layout over the wire and inflate that. Unfortunately, Android XML layout inflator does not take in plain XML. And it is for performance reasons. So I can explain how the layout inflator actually works, right? I'm going to try to explain it again, but from a different angle. So how does the layout inflator actually work? When you write your XML in your ID in the application, when Aspect Studio compiles it, the AAPT program takes in that plain XML and checks out of the XML, which looks something like this. So the stuff that you write in your ID in your app looks like that makes no sense. Okay. Then it also generates an r.java file. Now, if you open the r.java file inside the framework, it looks something like this. It is filled with public static final lines and it has view names and attributes all assigned some integers. And these are the same integers that are used in that binary XML that I just showed you. Okay. Now, when your application runs and you execute the method called layout inflator.inflate, it takes in r.layout.something. What actually happens is that this method goes and reads that particular file from the disk and then starts walking the XML dorm tree recursively. And every time it encounters a tag, it calls another method called create. This createView method, what it does as I clearly explained, is using reflections. It will create a new instance of that view. And this is where that r.java file kicks in. That r.java file is actually used to look up attribute values and assign it to the view. So if you open the view class in Android, it has a switch case and you'll see r.stylable.view underscore padding. This returns the int, which you can use to look up back into the binary XML and get the value which can be assigned to the view. And this is exactly what Proteus does. But Proteus does it on JSON and at runtime. So the reason that we went with JSON was that it's less verbose, lighter over the wire and easier to pass, therefore faster. Okay, so is it as good as the XML layout inflator that Android provides? Let's talk in terms of capabilities. You can build views, compose layouts just like you do in XML, as complex as they get today. Out of the box, Proteus comes with all native components and all attributes. There are so many that I could not put it up in one slide. So that's just the first few that I could. Okay, the next is runtime data bindings and formatters. So Sake talked about formatters and bindings, right? But in Android, the bindings that you get out of the box or using the external library is compile time data one. So I'm talking about runtime data bindings. Now a series of demos will begin. So bear with me. Okay, so remember that in the random method, I passed in another parameter called data. This data is actually a JSON object. Consider it as your API response. Okay, now let's say that this is the data JSON, right? This is what came from the network. Now instead of doing hello world, I actually want to show hello name. In this case, hello, John Doe. So in order to do that, I'll basically just go to my layout. I'll go to my layout and in the text attribute, it says hello world right now. So the first character, I'll change it to a tilde. This basically is a qualifier that tells Proteus that a data binding is going and any every data binding is basically a double curly brace and you can pass in passing the name attribute. So here you go. Now it says hello, John Doe. Now let's say tomorrow you also want to show location. Be careful that I'm not actually building the app again. I'm basically just pulling the layout and I'm re rendering again. So here I copy the text view again and in the text attribute. I'm going to show you the location. I'm going to location dot city and common location dot country. So you can give multiple data binding in a single attribute if you want to. And I'm going to refresh. That's it. You see that also. No app updates anything. Okay. Let's take it one more step ahead. Let's say tomorrow. Your API starts sending more information credits experience achievement. Let's say it's a gamer's profile and show this information on the screen right now. Let's say I want to show experience as a progress bar. So Proteus will give you a type call horizontal progress bar because there are two types of progress for a penalty. So I'm going to change the type of progress bar. I'm going to change the way to match parents. So everyone can see this now text size and text don't make any sense for progress bar, right? Max and progress the same attributes that you use an XML. So Max basically I'll set to if you remember the data Jason, it's experience dot max. So dollar here is another qualify that tells Proteus that a data binding coming. But this is basically a simple data binding that can only take one value. It basically improves performance. So I give progress as experience dot current. I can go ahead and refresh again. And here you go. You see the progress one. Okay. Now remember for matters. So I'm going to show you how for matters work for matters is exactly what you're thinking about it. It takes in an input chucks out something else and that is what gets displayed on the screen. So I'm going to show credits now. So I do credit and I hit render. So you see 39,550 but ideally any number you would want it to be comma separated, right? So I would actually want to format it. So in this case in Proteus, you can set a formatter. So number comes out or out of the box in Proteus. So to use a formatted, you do a dollar and in parents, you pass in the name of the format and that's it. You see comma separated values for the text. So style style is something else that you will also get. Not support style, right? But it supports tiles to a normal extent. You can't have multiple styles on the same view. Get another style with basically composition of them. So Android gives you styles, but not awesome. So Proteus, we have implemented another form of style. I'll go ahead and give another demo now. So let's say that everywhere I see credits. I want to give it a style throughout my application. That's the best use case for style, right? So credits is money. I want it to be large and green. So here I'm going to create a new style. I'm going to call it money. So a style is basically a key value pair and of attributes set to a name. In this case, I give text color and text size. Now down in my layout, I can just go ahead and add style attribute just like you do in XML and mention the name of the style here. Call money and I'm done. Okay, that's okay. But what if I want to apply another style to it? In this case, you can go ahead and add that style. I'm going to create another style called center, which is going to set the layout gravity to center in order to apply that to on this view. I just need to go back to my layout and add this style as a dot separated value. That's it. It's going to be centerline. Okay, so styles. So this was a style parameter that you passed in the argument. Basically a hash map in XML. You can also describe shapes and animation you can apply on your right and you can do the same thing in Proteus also. So I've already pre written some backgrounds and animations for you guys. So you can see it. Please don't mind my design skills here. So I created a background, which is of type shape and the shape is over and in the children area. I'm basically giving it all the properties that I want to apply on this shape in this case and given to gradient and in addition gradient has start color and color and an angle. And once I've done that, I can go ahead and refresh my screen again. Now you can see that all around that view. Cool. Moving on to animations. You can even do animations with Proteus. You actually don't have to go to a Java code and set an animation. In this case, I'm going to create a rotation animation and it has the same properties that you use in XML. There is no difference whatsoever. You give it from degrees to degrees, the pivot and the duration and this is going to be animated. Okay, now comes the cool part out of the box. Proteus will support all drawables, all animation properties. If you want your own, you can also plug that into Proteus. Now comes the cool part some views and custom attributes. You don't have to actually go into the code of Proteus to extend its functionality. You can actually plug in your own custom views from the outside. It's like teaching Proteus how to render and how to handle attributes of the views that you have created. So let's say that in this case, you're seeing a layout right here, correct? And at the top, you see a frame layout and instead of frame layout, I actually want to give it a card layout, give it some elevation and give it some rounded bottles. So back in my application, I've extended the card view to Proteus card view. Now I'm going to implement an interface on it called the Proteus view interface. This basically has just two methods, a setter and a getter, where you set a view manager. Nothing fancy here, just a setter and getter. Now, since now you can create a view using Proteus out, but you have to actually teach Proteus how to create a new instance of this and how to handle its custom attributes. For that, you create another class called as a card view parser. So a card view parser, so parser is basically an interface that Proteus exposes. You have to implement it. So in this case, I'm going to implement a type called a wrapable parser, which I'll come back to later. So this is going to ask you to implement a method called create view. This method is called by Proteus to ask you to give it a new instance of it. And you basically return the new instance of the Proteus card view that you just created. Now you need to teach it how to handle the custom attributes of Card View, right? There's another method that you've been over right called as prepare handlers. Now inside the prepare handler methods, you basically add all the new attributes that you want Proteus to learn about. In this case, I'm going to add an attribute called card background color. Now card background color is a color resource, right? It can take a hash value or reference of a color. So we have a color resource processor and when it comes back Proteus will actually give you the int value or the color state list, which you can actually call the method on the view itself to set it. That's pretty much it. You actually taught Proteus how to handle the card background color. Similarly, there's a card elevation, which is basically a dimension. So we have a dimension attribute processor, which in the callback gives you the dimension that Proteus has passed and you can call the appropriate method on the view that you use in this case. I'll call set card elevation. Now there are a couple of other attributes just that I'm going to copy paste that's card corner radius and the content padding. Now I need to plug this into Proteus, right? Now this is where remember I told you that I'll come back to the Rappable Passer. If you see the card, you extend the frame layout. So you would need all the attribute processors of a frame layout also. So you need to also have that behavior in the card, right? You have to give the layout weight, the layout height, the margin, etc. So you can basically ask a layout builder to give you the currently registered passer for a frame layout. And then it's just a matter of calling the register handle matter on the builder passing the name that you want to use. In this case, I'll pass it card view and a new instance of the Card View Passer. And here you will pass the frame layout Passer, which becomes its parent using composition instead of inheritance. Okay, so I'll go ahead and build my app now. I'll come back. I'm going to add the card view attributes first and then change the type to Card View. So I've added the background color, the elevation, the padding and the corner radius. I'm going to go ahead and now refresh the screen again. So now you see that it actually rendered a card view. So you can do custom attributes. Now doing something like this eventually problems, right? You're doing something new and you might end up making mistakes. So by default, Proteus is built in such a way that it has fallbacks and it has fail saves. So even if you do end up adding an attribute not associated to you, it will basically ignore it or you tell you do. I don't understand this. Please do it yourself. So that's a callback part of that I was talking about initially. Also, you will not have to make multiple layouts for different API as you can handle those cases as just in a statement. So what are the advantage? What do you get by moving to Proteus instead of XML? You need to do something completely new, right? There needs to be advantage. So the first adoption, the first advantage is basically zero adoption time. If you publish a new layout to your servers, the next time the user visits your app is basically seeing the new it. There is no adoption time. The second is you can even update older versions of your app. If there are multiple versions of your app out there with Proteus, you can actually once you publish the layout, even the older versions will get it. And if you are into A.B. testing, you can easily do layout based A.B. test matter of sending different layouts over the wire and testing them again. Now another advantage that you get is that you reduce our app size because the number of XML layouts that you have in your app will go down. Then you save a lot of development effort because every time you make a layout change, you don't actually have to build the application again. Though instant rent has now come, but we started before that. So you will save in development. So what did we do in the last one year? We have been on it for nearly an year. We have almost avoided four releases. There's four whole months of releases. We have saved months in terms of development. The number of A.B. tests that we have already run is nine and I told that we're going to run 11 more concurrently and we get near native performance. We have significantly improved the performance of Proteus of the past one year and it is as close as the XML layout inflator and saved of adoption time for our users. So is this the golden bullet for views in Android? Probably not. The first constraint that you can only modify behavior. You can only modify appearance and not behavior. There is no way that you can base logic over the wire sending descriptions of your views. Now as of right now, views which need adapters like view pages and recycler views and list views, you would actually have to handle them yourself. Proteus will not set adapters on your views. It will give you a callback saying, dude, this particular view needs an adapter that it now, if you choose to move to produce, you will actually invest in your structure. Hello. Okay, you would actually need servers that can transfer a layout stream to do a V test and do versioning. If you're into that now, we have a good back for Proteus. We actually want to make it the XML layout and to be as at Flipkart chose Jason to do our layouts right, but we would actually want to move this behind an interface so that any developer can implement any vision description language and then use that with Proteus plate your views. You would actually want to go truly into the layout and fit a Android by introducing dimensions and string tables and all the other stuff that the Android framework provides. So right now we have different environments. You'll actually have to make your own ID to manage all your layouts, but we would actually want to integrate into the Android studio so that everyone can work on it in a single place. Last year's in order to get new developers up and running faster, we would want to publish server side specs. There are other kind of one of them is Jason to view. Just very, very similar to Proteus. The only thing is that it does not have data binding styles, drawables or other cool features that there's one from Ali Baba called and fix and fix is kind of different because it sends or text files over the wire. If you try to do that place tour might actually ban your app. There's another less known one called it's not droid, which uses sort of XML and communication or server side views and something that I know is react native. So react native is you will have the opportunity to even send down business logic over the wire. It will be just a matter of sending down the entire JS bundle and then reading that and rendering your react native application, but there are onsite Proteus and react native are trying to solve different problems. One is react native. If you go with it, actually take up three of in your app on the other hand Proteus is around 250 and the learning curve is significantly different in react native. The learning curve is very high. Comparatively Proteus has a very low learning curve and it is open source and we definitely look forward to your contributions questions guys. Look, so when you explain that or some parts are right. So basically it has to follow the naming convention then basically you have to name it. Disturbed the card view as a card you can call it gibberish if you want to know. So when you say Proteus card view, which was a custom class and then you had to write a parser for that. No naming convention is whatever. You can actually call it my card view. That's basically just a name which we don't care about. Yeah, so my card view has to follow when you do parser. So my card view parser. That's what I know. Those parser takes in a generic. That's what you're talking about, right? So that I go back. Yeah, can you go back? Sure. Yeah. So and the previous one was Proteus card view, right? Yes. So it there. So between these two classes, there is no naming convention has to be there is no naming convention whatsoever. Okay. Actually, we have a custom library third party library for views. So can we import those libraries? Sure. Again, Proteus does not worry about you never have to actually go to the source code of Proteus. If you have a view, if it has public setters and getters, you can actually teach Proteus how to inflate a new view and how to handle this attribute. For example, I did it for the card, right? Card background color is not a native Android attribute. You can actually teach it how to do it. Hey, hi. Hi. So currently we are writing Jason at several sites. But I can't hear you. Hello. Jason fine. Do you have any ID support or some support? So in-house we have created a very small ID in AngularJSN node, which actually helps us publish it to the servers also, but it's not open source. We are not sure if we'll open source it or when we'll open source it, but we will definitely publish specs for it. So currently if you want to try any, you can use either sublime text notepad editor. You can use any editor that you want. Can you like take an example of different between a react native and Proteus, say for a feed or the home page of lip card? What would you prefer like Proteus or Reactive? So the question is basically what would be what would you use in Flipkart react native on the home page or would you? So yeah, what would be the advantages and disadvantages of both the produce? So the question does not actually come to the Flipkart homepage or anything. It depends on your use case. If predominantly the changes that you want to make or the page itself has less business logic and the business logic is not going to change frequently. Go with something like Proteus because it's very, very small and your developers can pick it up faster. On the other hand, if you have very complex business logic with changes over time and you want the ability to push it over the wire, you should go with react native. So how do you handle like different versions of the app? Let's say you have a version of an app out which and there's another newer version which has a custom view. So does your server needs to kind of know, okay, this version of the app cannot support card view and this version can and like send different data over the web. So you basically talking about versioning, right? Normal standard versioning. Yeah, an app is requesting for a layout. There might be multiple versions of it. Yes. And if I remember in the slide, there was a roadmap section where I said server side specs. These are the specs that we have defined that we are currently using in Flipkart, which enable us to actually do this. So when a device asks for a layout, it is also sending some meta information about which app version is it, which features that it have. And on the server side, it actually chooses which is the best layout to serve this guy and it's going to send it down. Okay. So we will try to publish server side specs for it. Implementing proteas or I will implement it is the presentation. You said that you will be also requiring good servers to handle the views, not in terms of the capacity of views, not in terms of hardware. I'm not talking related to hardware performance when I mean you may not have such a back-end right now. Let's say if you are using PHP or Node.js or something, you'll basically need a new API and a database for it. That's it. But every time proteas view is used, there will be a hit for a JSON on the, not necessarily. It depends upon your caching strategy. Exactly. So I mean, if I use it, I will obviously wrap it up in a caching strategy with a version system, if it is inside proteas itself, it will make it much more efficient. So we have plans around that, but we will not give it as a core part of the library because different people might want to use different caching strategies, right? We'll probably have it as a sub-model. And the other thing is proteas in essence is stateless. Once that build call goes, proteas doesn't even remember what just happened. Just like layout inflator.inflate has no idea that, you know, it is completely stateless. We are also stateless. So the caching mechanism cannot be part of proteas. Can be plugged in from the outside. If you want to show some animation, yes, I want to know whether you have any metrics or like how performance is it as compared to Java? Okay, I got the question. Your question is basically I did animation and how performant is it correct compared to native? Okay, so we are not actually doing anything new that JSON object that I created for the animation is actually used to create a normal native animation object, which it does even in the case of XML. Whatever XML that you write when it's red, it actually creates a Java object out of it. We are actually just creating that object at runtime. So there is no difference whatsoever. The performance is exactly the same. No, it's the same object that Android also created, right? It will also create it at least once. We are also creating one. I just want you to understand how do you handle the first time you had inflation in an offline mode? So you just like supply the initial. So the question is about offline mode, right? If the user is offline, will the view render or not? No, so how do you handle the first time? So there is an option here. What you can do is it again depends on your use case and your strategy. The simplest method could be that you can bundle the JSON objects or the JSON layouts that you want to use for the first time within the application. Hi, I just wanted to know like whether there are any tools to preview the layout that we are actually actively working on creating a tool that can render the JSON to an actual layout, but then again, there's another roadmap that we have to move away from a very, very concrete implementation and move it behind an interface so that you can create your own visual language. We don't have it today, but we are in the plans of doing it. So you showed an example of an A-B test where you and on the right side had a thumbnail of the dress and on the other hand, you didn't have any thumbnail. Sure. You definitely used Proteus for that. Yes. But how did you deploy your business logic over those thumbnails? So that thumbnail is basically just there in order to view your actual exercise. So what about that? In this case, in this case, the image that I actually showed you had thumbnail, right? It was just one thumbnail. If there are multiple thumbnails, the behavior for that was already pre bundled in the application. So our application is built in such a way that we work on actions. If switching a view with an action, I can use it anywhere I want. Okay. So you actually need to at least deploy your app once for that A-B test. Correct. So if not an A-B test, if there is a new behavior, then you have to do an app that I've already mentioned that it is not a golden bullet for behavior whatsoever. Thank you. So Proteus, do you plan only to do, you know, things like A-B testing or say I have a form and I want to add a Dropbox. So right now Proteus just chucks a view out, right? It doesn't take any input. So we had actually implemented a form system or a form-based architecture for Proteus. And it was in the development phase, but we had to move forward because we had other pressing matters to look into. But yes, that is also in the pipeline. Yes, that is a very important use case that we want to solve. Hi. Hi. So you can, so the JSON data will probably be coming from the server so you can add more data and you can also display based on the layout. Correct. So then this changes how we plan features, right? So typically. Yes, you have to plan less. Yeah. So can you give a brief idea about how you go about planning on what to do? So it won't be any different from the way you do it today, right? So let's say I want to develop a new feature. You will, product manager will come, your designer will come, they'll give you mocks and they'll give you tons of other stuff, right? After that is done. You can basically either ask them, are we into a bit as change? Are we doing that? You can create the layouts in the first place, right? After that thing is done, you ship your app. Everything is out there. Now you have just one option when she is the layout. Right? So there is no planning as such. If ad hoc request comes to let's say go ahead and add a subtitle, you can do that. That's basically the feature planning that you have to do anything that needs to be any behavior that needs to be implemented needs to be done before the app is released. Okay. Just like before. So like you said, switching to a different view is an abstract action that can be used anywhere. Yes. So that is not part of Proteus. That is some sort of a component architecture that we have been developing at Cut and probably we might open Sosit one. Okay. Hi. Hi. Say like, you know, views is good for views. Okay. But even if there is one user interaction that the use one user action that the user has to change. Correct. So Proteus cannot work on that. So out of the box, Proteus will give you no such thing. Right? If you have created a view and you expect it to have an image view, you can find that image view with the ID and set your own listeners again. The moment behavior comes into picture, you need to pre bundle the behavior in our app. Proteus will only solve. Appearance for you. Not behavior. Thank you.