 a senior engineer at Circles Life. Majorly, I concentrate on the Android stack. And I also have experience in backend systems or big data field, which I've done in my previous organizations. One really good thing about our organization is our missions. So these are our missions. If you haven't already downloaded our application, you can do so now. We have a great data platform wherein you can see, I mean, what all engineering we do is really visible in the application. So the smoothness of the application or the backend services we have integrated, or the data platform, also, which we have on the application, it's very intuitive of how we gather data of different people and then, or different events and then present them in a fashion so that people benefit and get to know which events are going on around them or nearby events. So yeah, that's it. The data platform I was talking about, it's one of the most futuristic digital telcos currently in and around Southeast Asia. So we are going to talk about RxJava. Anyone has any idea of what RxJava is or what is it used for? Of course. So basically, Rx is not only limited to Java. It is entity in itself. It's reactive extensions. And it can be modeled with Java, Scala, or any other language on iOS, any language you can think of, we can model reactive extensions to that. Normally, we hear about object-oriented programming. This is the fundamental of functional programming. So with Rx, you not only can implement functional programming into object-oriented programming, but you can go with the functional programming and implement Rx on top of it. And it will solve your problems, a lot of problems which we'll detail about in a few minutes. So it's a bit hard to grasp, of course. Sorry, what exactly is Rx? Reactive extensions. What is that? I'll come to that. The session is all about that. So it's a bit hard to grasp in the beginning. But once you get the grip on it, it is a part of your daily life in and out. You won't do programming without Rx. That is how we in the organization are right now. Both the teams, iOS and Android, we cannot live without Rx. It makes your life a lot easier. So the first question would be, what problem are we trying to solve with Rx? I would say that consider a scenario wherein we have a mobile application and we just want to authenticate the user to login and then load his profile page. This is a real-life scenario wherein a lot of people who create applications have this authentication mechanism. And then the profile page tells the user what his profile on the application or on the system is. So we need to make backend connections for this. So to make these backend connections, if you have an idea of how Android works, it has a main thread for loading the UI of the user. And everything you need to do to fetch from the server or if you want to do some calculations, you have to run it on a background thread because I hope your threading is comfortable with you guys. Yeah, so you have to run this on a background thread because if you run it on the UI thread, your UI is going to freeze. It needs computational power. Your mobile phone is very limited on resources. So each time you do a network call or you do a database computation, even if you are loading something from a file, you have to do it on a different thread so that your application doesn't hang. This majorly is part of the asynchronous fundamentals. So you have various ways to do asynchronous things, like keep the UI on the main thread and do some background processes with a different thread and then load those results on again to the main thread and then display them to the user. Let me know if it's all coming properly. We can have an interactive session. Yeah, so the problem we are trying to solve is that our users should not face a problem with our application. The data should load properly and the UI thread should never hang. You ever played a game or something wherein the game hung on you or frozen on you and you couldn't go to the next level or just crashed. It's very, it gives you a lot of bad repetition on the Play Store, first of all, as a developer. And second, your users are not happy with you. So this is the problem we are trying to solve with Rx. Okay. The fundamental pattern which Rx works on, the bare bones thing is the observer pattern. So any idea with you guys how the observer pattern works? Okay. So I'll just explain it again. Observer pattern, this is the dictionary definition of observer pattern, but I'll give you an example. Say for example, you guys are looking for a job tomorrow and you want to get updated jobs relevant to you. So each time either you have to go to the job listing organization and check whether new jobs have come or not. Or the other way to do this would be you subscribe to the job listing organization and whenever there is a job which is relevant to you, it gets posted to you. Similar like how you shop on Lazada and you get a parcel and you get a notification. Hey, your parcel has reached. So notifying one-on-one. That is what observer pattern does. Or if you have, you can think of a game wherein you want to create a reward system. So the user does some action and you want to reward him. So if user does 100 miles run, you reward him. If he does 2000 miles run, you reward him. Or if he climbs 100 stairs. So there can be multiple scenarios wherein you want to reward the user. Either you can write this boilerplate code within each class which will increase your complexity. You can write booleans and a lot of conditions. Or you can create an event manager which is based on observer pattern and which notifies these receivers that hey, a new event of your interest has come. So you can take action. So I would want to demonstrate this with code. So we start with, I think, yeah, I'll just, yeah, I'll just increase this one. Okay, that's fine. Yeah. So we start with the subject. The subject is like the thing which is to be observed. The thing you are interested in. So a subject, this is an interface. This is Kotlin. If you guys already don't know, then this is the next thing after Java. Yeah, it is going to eat Java. That's my preference and that's my understanding, yeah. So we define a contract first of all, whenever we are creating an observer pattern in which we have three methods which every observable thing, a subject has to override. So that would be addObserver, removeObserver and notifyObserver. And we also have an observer. Observer is like Jack. Jack is interested in knowing, I'm sorry. Jack is interested in knowing if there are any new job updates. So it can be any person. This again is an interface. This is just defining the contract between, this will define the contract between different classes. And then yeah, then we have the job listing organization which extends the subject interface which has a list of observers and a job list. These two are class-level variables because it will contain all the observers which are observing on this class which are interested in knowing, getting notified if anything is added to the jobs list. So as per the contractor in subject, we have addObserver and removeObserver and notifyObserver and get all listings just for the updates of all the jobs. You guys can ask me questions if it's confusing at any point. And we have a listing also. Listing is just Pojo. Do you guys know what a Pojo is? A Pojo? Yeah, Pojo is a plain old Jano object which is only responsible for holding data. You, with getters and setters, it's so easy with Kotlin. You don't have to write all the boilerplate for Kotlin. No getters, no setters, just define it this way. And this is the listing which will contain the name of the recipient, the job seeker and the address of the job seeker and the title of the job. It's just a data holder. And now we would write the concrete class for the job seeker who is the observer in this case. So you can consider job seeker as any person, even me who is seeking a job. And the job seeker will get notified in the update method which is overridden from the observer interface. And we have a helper method over here which reads the job list. If listing.name is equal to name just refers to that if the listing was referred to this person. If the listing was referred to this person then he can read the listing. I'll just give a quick run. I need to explain. So we are registering two job seekers, Jin and Hiyashi. And we are creating one job listing for an Android programmer. And job vendor is the job organization. And we are letting Jin and Hiyashi observe on the job listing organization. And we are adding only one job to the job listing. This is to be sent to Hiyashi only. So in this case, Jin doesn't get any job listing because his name is not mentioned. So this is the magic of observer pattern. When you run it, it should only give the notification to Hiyashi. I probably cannot increase the font on my command line. But yeah, it's to Hiyashi with the title Android programmer. So this is how we have notified different recipients of the job opportunity with an observer pattern. Any questions on observer pattern? If anything is not clear. You thought this is still running unsynchronously, right? No, this is not running unsynchronously. This is running on the main thread. We'll get to a synchronous pattern. This is just to represent how data is flowing to multiple recipients, whoever are interested in it. Okay, after observer pattern, let's move on. Yeah. So RX is an observer pattern on steroids. You don't have to write this much of code to get an observable or a subject or to notify users. Not only that, we can also say that, yeah, again, the problem we are trying to solve is basically getting a synchronous with our data. And apart from that, if say for example, while making an API call, you are getting a person's name, his age, his date of birth from three different APIs. And you want to greet this user. Now you either have to wait for the response of these three APIs and then trigger the greeting because you have to write a greeting like, hey, Jack, how are you today? Your date of birth is this and it's a Tuesday today. Say for example, all this information is coming from multiple APIs. And in order to process this information and put it in front of the user, you have to make three API calls and you have to wait for the computation. Maybe you write three different methods. Maybe you write three different background tasks. Then you have to collate this together and then present it to the user. You can make analogy with this concept like with the job of a carpenter. Carpenter gets his raw materials, the wood, he chops it, he designs it properly, he polishes it, he adds glue to it, he makes a fine product and then only he can sell it to the market. So programmers are no different. We also have to take this raw data, then polish it, fashion it and then sell it to the user so that the user likes it. So this is the way of Rx because you're writing so many methods, so many functions to model your data according to the user needs. Rx provides you means with which you can just take this data, map it, filter it, check whether it contains some data or not or polishes it according to your preference. You can define as a programmer what you want to do with the data and how you want to present it to the user and in an asynchronous fashion. So you only get notified when the data is ready and when you are finally going to put the data in front of the user. And the same thing which I said that being programmers are gods are the users. They can give you good reviews or they can do new to the gates of hell. So we have to take care of our users a lot. The app should provide them the value which it promises them. It should always be helpful to them in the need of crisis. Anyone knows about background tasks on Android how they are performed? Okay, so I'll give a brief example of like what I said before that in case of Android we have one main thread which runs the UI and one background thread all your CPU intensive tasks or long running tasks have to be carried out on a background thread and the UI thread has to be left to display content to the user. If we do something on the main UI thread it will cause a lot of irritation to the user. The app will hang because there are limited resources only three or four cores of CPU available on the phone. So if you run with it with the this is a very intuitive and the first and foremost background tasks provided by the Android framework. It started when Android one came. It's an async task and there are two methods in it. Normally whenever you make an API call on Android this is the choice you take without RX. So these two methods do in background and on post execute. You can think of these as do in background is your workhorse. It will do your API calling or any competition which takes a long time and on post execute it's a handshake between the UI thread and the background thread. So all the tasks which have been executed in do in background and the results you're interested in will be posted in on post execute. This is a boon. This is a bane. Think that you're making multiple background requests and you want to collate that data together. So you have to write multiple async tasks so that you get the data in on post execute of every async task and then you have to collate that data outside of this async task and then show it to the user. This is a pain. This is where RX is helpful. And yeah, there is no control over when you trigger it. There is no control over when you get the results and no control on how you can manipulate it. I think because no one is aware about async task so I'll drop the, can you think of more? Yeah, the concept of RX started with the same frustration when users, when we had to do a lot of async task and a lot of things in the background then coalesce them together and then present them to the user. It was something which you wouldn't want to do because you would want to concentrate more on the architecture of your application rather than writing HTTP calls and coalescing the results together. That's a menial job. So RX came into prominence when Java 8 released streams. Stream is something with the same analogy as a carpenter. You have a source and a source emits some data. You have the power of manipulating this data and you have the power of manipulating this data and then displaying it to the user. And a source, a stream always has a source and a terminal event. So a stream can be thought of as a river also or a factory where in raw goods go they get processed and a final product comes out. This is stream in Java 8. So RX Java came into prominence when streams were released and it built on top of them. So we just saw the observer pattern. It's very simple, simply put in RX Java. There are observables and there are subjects like we just saw in the interfaces. So observables and subjects together let you manipulate the data, the stream of data I would say now and make it polished so that it can be presented in a very fine grained manner to the user. Yeah, back to code. Okay, this is the simplest form of an observable. It is just saying that observable.just means that observable is a string named hello. Just one line of code and observable is created. Till this point, we are just creating an observable just saying that this observable contains a string named hello. And till now, there is no processing in the system. The subscribe now is a subscriber and it has got three inbuilt functions. It has got on next, on complete and on error which are detailed in this one is the on next and we have the on error and on done or on completed. Till the time you've created an observable, there is no processing in your system. And once you subscribe to it, then the chain of events kicks in. So when you say observable.subscribe, it will start manipulating or printing out the data or whatever you want to do with the data. So it's on next, the subscribers on next gets kicked in. And finally, if there is an error, there are only two terminal events in an observable and a subscriber contract. If it gets completed or if it errors, that is a time where it terminates. It is a terminal event. After that, you cannot expect your observable to do anything or your subscriber to send you more data. There are various ways of defining these observables. Here I've created an observable out of an array. And again, to make it more simple, I'm just creating an observable first and then I'm just subscribing to this observable. I'll just run it in a while so that you get a better understanding of this one. Here we are creating it from an array but the most fundamental form of creating an observable is with the create method. In here, we are telling an observable to carry three values of type integer, one, two, and three. So whenever anything subscribes to this observer, it will emit one, two, and three values in its on next. So we are just defining an observable over here. And when we are subscribing to this observer over here, it will come in this on next three times because we are sending three values from the observable. You can think of this analogy in terms of networking or doing any expensive operations. This is just for a demo purpose that I've written one, two, and three over there. But in real life, you would want to do any expensive operation over there. And once you subscribe to this observer, if there is an error, that would be the terminal event, it will stop. And if there is no error, it will print or execute normally and then do its on complete. We'll run these three examples. Our question? Yeah. I'm not very clear what the on next function is for. I understand what on complete and on error is. Yes, so there are two forms of on next. One is the on next of the subscriber, of the observable. And one is the on next of the subscriber. So subscriber and observable. In observable, whenever you're creating an observable, think of creating a job seeker company. So in this case, you're telling that whenever someone subscribes to me, I would emit three events. That is one, two, and three, one after the other. So that is on next. And over here in subscriber, when you're subscribing to the observable, it will print this one, two, three in its on next. So this subscriber also has an on next method and on complete. And over here in observable also, we have an on next method and on complete method. Yeah. Okay, one last one to demonstrate about errors. So any idea what this code will do? No? Okay, I, yeah, it will throw an error. But I also want to introduce a new variable over here, which is retry. So normally when you're writing something and it fails, when you're trying to compute something and it fails, you would want to retry. And imagine the boilerplate you're putting into that while loops or for loops and then keeping the state. It all gets simplified in Rx. You just have to say, if it doesn't run on the first time, just retry this many times. So this is also a keyword which is provided by Rx. It makes your life very easy. So yeah, you're correct. It will throw an error over here and it will directly come in on error. That would be a terminal event and then it will retry two more times. Let's run these three examples. Okay, I'll just copy this log and make it more intuitive over here. This is one from the previous one. So this is the one we saw first, just one word. And this one is from the array. So you see, sorry, this is from the array from here. And so you see, we are also getting the done methods called in on complete. And the observer wherein we demonstrated, we can send multiple events through an observer like one, two and three or four. Any type of computation we can send in a stream. Okay, and the last one wherein we three one error. We have three retries and one main try before it errored out. So this is a terminal event. It will not go beyond this. And any questions regarding this part of how we did on next or ran this whole thing? Let's just have a remark. So one of the things would be very, very clear. What you showed is a string, an array and an event source, which usually when you write code, you have to add a little bit of a string. You just, well, you add it or you print it out. The array you have to loop through the event source, you have to write an event handler, the headache, especially when you change something from an array to a string, you have to rewrite your code unless you use as he just demonstrated your RX. You have a single pattern regarding of the nature of the data you want to process. Thanks. You're welcome. Okay, I would move to RX operators. Very interesting topic. Question. Yeah, please shoot. It seems like RX provides a lot of code. Is there any content to using RX? Not any I can think of. Unless, unless, unless, yeah, the learning curve is huge. But trust me, trust me, if you get hands on RX properly, there is nothing you cannot do. It is applicable to every language out there and it also gives you a very good intro to functional programming. And then if you know functional, you can go into machine learning. You can do functional on mobile phones. You can do functional anywhere. Functional is recently gathering more of tension than object oriented. Okay, so we'll go with the operators. So, yeah, sorry. Any performance overhead by using this? No, it will make your systems more scalable because you are not concerned about threading, you are not concerned about handling how your results are calculated. The creators have taken a lot of effort in how your threads are managed and how your results are derived. So, in fact, if you want to scale your systems or you want to make your systems more reliable and more faster, RX is the way to go. But the only caveat is that you should know it in and out, you should not do any mistake in calling it or just forgot something and then it increased the load on your machine. It's a very, but the thing with this is that you as a programmer have to define or to decide for which problem you would want to use RX. You wouldn't want to use RX for summing up one plus one. You would want to use RX to do some good stuff, to call a network or to help you with a task which is meant to be solved by RX. So, that decision making, of course, is up to you as a programmer. It will come with experience. Okay, RX operators, there are billions of operators. I can't remember all of them, but just to give you a flavor of it, say for example, you have an array of numbers and for some reason you want to just add one number to each number in this array. So, normally you would write a for loop and then take one element from the array and then add one more, one digit to it and then store it in a different array or just print it out. So, imagine writing all that code again rather than just taking leverage of the streams provided by Java and the map function. So, it's as simple as this. We just provide a basic map operator and for every number in this map, in this list, we map it to number plus one and then just subscribe to it again. Bonus point would be if you can tell me what this function is and yeah, guess the block. We have three blocks in the subscribe. Okay, I'll give you a hint. This would be the on error block. Yes, correct. And the one in the last is the on done. Okay, this is one operator map. We have a filter also. Filter will just filter your input and process the output as per the filter you've defined. Say for example, I'll give you a real life scenario for this is a very simple scenario over here. We're just filtering on the basis of number mod two is equal to zero. If the number mod two is equal to zero, we'll print it. Otherwise, we'll just ignore it. So, you have an array wherein you have multiple numbers and you want to filter it on basis of something in this case being mod two. But a real life scenario would be that you get a lot of data from the server and you want to filter it. You don't want to show some sensitive information to the user. You can use a filter over there. Or for example, you're subscribing to a server and it returns you a null in your subscription in an HTTP connection. It should not crash your application. You should handle it on the client side. You should probably put a filter, not null. That is again a filter on top of all the data you are receiving from the server. So, that way your users will not suffer with an unexpectedly this application crashed. Rather, you will handle it very gracefully and tell the user that, hey, our server or our backend things are not working properly right now. Maybe you try it on later again. So, that is the power of these filters, actually. We'll just run this for a demo. This is the demo. So, this is the output of these two methods. Two, three, four being the output of the first method. I'll just highlight that again. So, here we have just added one number to the numbers in the array. So, that gives us an output of two, three, and four. The initial numbers being one, two, and three. And in the second scenario, we had done a basic filter operation in which we were interested in numbers which would be equal to zero if modded by two. So, for that, we have two, four, and six from that one, two, three, four, five, six array. So, this is the magic of Rx. I have a bonus piece of code for you guys which would be for networking. The thing I've been talking all the while with you. This is again based on a retrofit client which you guys might encounter if you want to do HTTP on Java or Android, retrofit and OK HTTP. It's not a traditional HTTP URL connection. It's a library built for you by Google, by someone who's working in Google, very big name in Android, Jake Wharton. And it's very easy to use with Rx. So, over here, we can also get to know the other patterns in Rx. So, we are saying there are two more things. GetUser is API call over here. We are doing an HTTP API call which refers to this API. The server is running on my local host and the endpoint is username. So, I can show you the server code running on the other side as well. Yeah, it's here. Again, the server is again based on Kotlin. It's a very nice language. Okay, so we have three parts for post methods over here. Yeah. Okay, so in the server, we have three parts. The username, the age and the department of a person. Say, for example, a person who wants to join a boxing club. And we have three APIs in over here for GetUserName, GetUserAge and GetUserDepartment. This is using an observable. And name model is again a pojo as defined earlier. As I deliberated on that, a pojo is just a data holder. So, whatever the API returns will be stored in an observable and would be of the type name model or age model or this should be department model. So, the main thing you would want to focus in API when you're calling an API from Rx is that I have written a subscribe on method over here which is schedulers.io. This is the fun part of Rx. Schedulers on IO means that whenever you're making this call whenever you're hitting the HTTP server do it on a thread different than the current thread. It's a scheduler's thread. It's a thread pool, unbounded thread pool from where Rx can take its threads or take its worker threads and execute work on them. And then again, again for the second one for name I've written a subscribe on schedulers.new thread. In this case, it's always creating a new thread to run its worker task. So, you have a fine-grained control on which thread you want to run a task on or on which thread you want to derive the results on. Yeah. Schedulers on IO is the input-output thread, right? Yes, it's an input-output thread. Yes, the main thread which handles the input-output? No, because we are specifying your code over here is running on the main thread. This function is getting called from our main thread. But when you're subscribing on this observable, it is telling the observable we are determining in the observable that you have to do this work on a scheduler's.io thread. So, a scheduler's.io thread is a bucket of unbounded thread pools. And these threads can be used to do worker tasks like background fetching, database or file opening, closing or a long-running operation like reading data files, manipulating them or anything. So, I have also outputted the thread name when this API gets called. We'll get to know which thread was used to do this task, apart from the main thread. Same case over here. And this is for department, just simple one. After these three, I'll show you another method which is of very much importance and very interesting. Again, let's just first run these three. Okay, so the first one in which we wanted the username, the server, we made an API call to the server. So, we have the username as Heshyang and the thread name also. So, this thread is running on a different, this is running on a different thread than your main thread. It has taken this thread from the thread pool. Same thing for the user age. We were using a different thread. And in this case, in the case of user age, in case of user age, we were just giving it a new thread which we had created. So, the difference between the two is that in one instance, we created a thread and gave it to RX that you run your worker task on this thread. And in another, we asked RX to determine whichever thread it wants to take from the thread pool and run on that. So, and this is the third one. For the wait, for the department, sorry. So, all good over here. I have three APIs, I make three API calls and I get three different results. But what if you want to greet the user like, hey, Heshyang, your wait is 26 kgs and we select you for flyweight boxing. Either you can wait for these three APIs to complete individually and then coalesce the results or you can use an RX zip operator wherein you tell RX that, hey, these are the three APIs you need to call on three different threads, parallelly, and get me the results. And also, coalesce those results together and give me the final string. That is what is happening in the last method. I think I, yeah, yeah, this is the method. So, we have three network services over here. Get username, get user agent and get user department. Another thing I want to demonstrate over here is that I'm using a single over here. I'm not using an observer. I'm using a single because single is a subset of observer or observable wherein it only emits once, one dataset and it either stops or it only emits an error. In a, in case of an observable, you have on next. So, do this on next, do this on next. In case of a single, single is basically an implementation on Groovy and Scala. So, it's a subset of observable and it only emits once. In case of networking, you would want it to be single because it's only a one-time operation. It will not emit anything on next. So, there are three APIs we're calling over here and these three APIs will return us three different things which is a name model, age model and byte model and the fourth parameter over here, this is a functional interface converted into a lambda. So, the third thing over here is a greetings model. The greetings model I'm providing because I want all these three coalesced into greetings model and I want to present that greeting model to the user. And I have a helper function for doing that. So, this is my greeting model. The major thing, the most interesting thing in this whole method is this single call. So, what it does is that it zips together results and then we are modifying the results over here to fit our greeting model. And we can just take this greeting model and show it to the user. Consider, think of it in this way that you're calling multiple APIs and then showing a page to the user, his dashboard on the application or the website you're creating. So, all your data is collected together on three different threads or multiple threads and then coalesced together on multiple threads then given to you on a UI thread. And then you just have to display it. How efficient and how easy it is to do. So, that is why let's just run this. I think we had already run this and we have the result. So, earlier we saw that these three were given us in a separate API call and now it's all coalesced together in one API call and we are just displaying it to the user. So, that's it from my side for the RX part. But, let's see what we have in the presentation on next. Okay, any questions? And also, Circle Life, we are hiring. Software engineers for Golang, Node.js and Android engineers. You can just take a photo of this if you want it for reference. We are also hiring interns.