 I'm very excited to be here at DroidCon India. It's my second time to the country only. So thanks to Hasgeek and everyone involved there for bringing me out to Bangalore. I hope you enjoy my talk, as well as my talk tomorrow. So before I get started properly, I'm Australian. Apologies if I use any strange words if you can't understand me, anything like that. I'll be offering advice on my accent at, I think, three o'clock today, I think. In the speaker connect room. So I'm from Hobart in Tasmania. So before I get started, Ricky Ponzing, David Boone, you all know about that. So I've been working as an Android developer for the best part of three years now. And one of the great things about working in mobile is that the field changes so much. And every job I've worked in the field, I've come away with a different and interesting story to tell. This one's about the job I work for currently. I'm going to be talking about the challenge of building mobile apps that run on multiple platforms. Now, I don't know about your experience, but mine is that for every time I've developed an Android application, I've been doing it alongside an iOS application of some sort. The project I'm working on is slightly different in that we have a really large common code base that runs on both iOS and Android. And I'd like to explain to you how that's done. So now, when you think about cross-platform apps, the most important players are things like PhoneGap or Titanium or Accelerator, things like that. These produce 100% cross-platform apps right down to the UI. Now, I'm a view of that making apps 100% cross-platform doesn't lead to the best results on any platform that you can target. You need to make separate design decisions for each platform, and that usually involves using each platform's native UI kit to make the best possible app you can on any platform. But you already know how this talk's going to end. You've read the title of the talk, you've read the abstract. This talk is about making cross-platform apps with native UIs. By having our core logic be portable, but by having UI in the native toolkit of the platform that you're using. And the platforms that we're going to look at today are iOS, Android, and Android. So, yeah, that's the talk. You can do this. It's great. Do it. It's completely possible to do this. It's a good idea. We're shipping an app that works on both iOS and Android, and the bulk of its code is the same. So what I'm going to focus on in this talk is something completely different. I want to know how we got to this point. So the talk I'm going to talk about is things that I wish we'd known when we started on these efforts, lessons that we've learned, and design principles that we've adopted since we started this project. What do you need to do in order to design an app that can run on multiple platforms? So rather than looking at code, I'm going to be looking more at engineering concepts instead. And the most important thing that I want you to take away from this talk is an understanding of modularity and software design, what it is, how to spot it, and what it lets you do. The payoff for this talk is that you'll understand the engineering tools that are necessary to make cross-platform code. So we're going to cover three things. The first is some engineering theory, how to think about app design to make your code portable. Then I'll show you a possible pathway to making portable code that runs on both iOS and Android. Once you have usable portable code, you can put a UI on top of it. And then we'll look at some design patterns that make designing portable code much easier. So let's begin. First up, we're going to talk about how to produce a modular piece of software. I'll cover some ideas that hopefully you've seen before when writing software, but I'd like to do a good job of linking these things together in your mind. So you'll hear at a mobile development conference. So you'll probably know about mobile development, right? What's astounding to me is that mobile development is only really a new field. Mobile development, as we know, it didn't really happen until 2008. That's when the first iPhone SDK came out and the Android version 1 came out in the same year. Now, five years is quite a long time in computer terms, but I want to go back even further. We want to go back to 1974. In 1974, your TV was still in black and white. James Bond was a comedian in fled trousers. Richard Nixon was running the United States and this man here wrote a paper called On Scientific Thought. Now, this man here is Edgar Dykstra. You've probably heard of his algorithm and things like that. Well, he wrote a paper in 1974 in which he was asked how best to analyze a computer program. Now, he noted that for any program you can consider any number of things as worthy of analysis, but that rather than considering them all at the same time, it's best to analyze things as a sum of their parts. Considering each aspect separately allows you to think about how each part of your program works in isolation, and then you can only think about two aspects when they interact with each other. This thing has come to be known as a separation of concerns. You might have heard about that. Now, Dykstra was actually asking his talk how to analyze the performance of an application, but these days we think about separation of concerns as dealing with different subsystems within a greater application. So what is separation of concerns and why do we care about it? Well, to answer that question, we first need to know what a concern is. According to everyone's favorite knowledge source Wikipedia, a concern is anything that has an effect upon the system as a whole. It could be something that interacts with a database. It could be something that displays things to a user. It's basically anything that can affect any observable part of your application. That's pretty vague, so let's look at things that don't have separation of concerns. Or actually, firstly, just separation of concerns is the act of dividing things in your application. So each observable part of your system is dealt with by a different piece of code. And in particular, separation of concerns means that you can design each aspect of an application separately from each other and only have these aspects interact when absolutely necessary. So here's an awful diagram to explain what doesn't have separation of concerns. An app where concerns aren't separated has all the features of the application in one logical piece of code. Now, if you've seen really bad PHP scripts, you've seen something that looks like this. This is something like SQL queries on one line followed by outputting a line of HTML on the next line. The concerns of querying the database and outputting information aren't separated there. An app which does have separation of concerns has several logical units of code that are only joined at a very small point. Now, the point where these two separated concerns meet is called the interface. Now, when you're talking about designing code, this is called the Application Programming Interface, or API. So the key observation at this point is that if you have code that exhibits separation of concerns, it is modular. So we know what separation of concerns is. Now, what's important is why you'd consider it as important at all, why you should consider it. So say you have a massively multiplayer game of some sort. I'm not going to name any brands here. Sending stuff across a network is a pretty important feature of apps like this. Because it's multiplayer on online, you need to communicate with other players over a network of some sort. So you're going to need some sort of network to send things over. Now, say you've also got on the same thing a banking app. Internet banking applications need to contact your bank so they can find out how much money you have. Now, these things seem like they have completely different purposes, but they've actually got a pretty core feature in common. They like to send stuff over networks. So you can think of these apps as something that sends stuff to a place, but you can think about it differently. Instead, you can think about what you want to send and where you want to send it. These are two separated concerns separated by an interface. That interface is your TCP IP sockets library. Because basically to an Ethernet cable, there's no difference between a banking app and a game. Now, this is a pretty powerful idea. You might think of this as trivial, but until very recently there was no difference in terms of how things worked between the telephone and the telephone line. Once you had the idea of separation of concerns, you got the Internet. Other examples of separating concerns is, for example, a splitting CSS from your HTML and your web pages. And this is just a concrete example of separating information from your presentation to separate concerns. Now, to conclude our discussion on modularity, there's one more thing I need to explain. The consequence of making modular code is the existence of a thing called coupling. So when an interface, that's some code in one module needing to interact with another module, and when that interface is implemented, this generates a point called a coupling. Couplings are two points or a point where two modules become unavoidably linked. The more coupling is required between two modules, the less separated the two modules are. So coupling comes or has many consequences, and I'm going to describe two of them. The first one I'm going to refer to is breadth. Breth refers the full range of places that you need to implement in order to fulfill an interface. So where all the joins are between two modules. If you have two features, then broad coupling means that you have lots of points that need to be joined in order to communicate between the two aspects of your code. In object-oriented terms, this means you have lots of methods at your interface, and each method communicates a very small amount of information. If your coupling ends up being very broad, then there's effectively no difference between each module. They're the same thing because they're joined together at every possible point. So there's no point in separating it. Now depth refers to the amount of stuff that you need to communicate at a single interface in order to get information between two parts of the system. Deep coupling is code that minimizes the number of coupling points, but in doing so has to provide a large amount of information at each coupling point in order to make the interface work. These in object-oriented terms look like methods with lots of parameters or parameter objects that contain the information that needs to be transferred. If your coupling ends up being very deep, then it means that you're basically transferring all the state from one module to another. Basically, no modularity there, either. So the takeaway message here is that the stronger the coupling between two things that could be modules, the less you can consider them as separate parts. So here's a graph to help you figure this out. If you have deep coupling, then you maximize the amount of information transferred at the interface at the expense of ways to transfer it. If you have broad coupling, then that maximizes the number of points where information can be transferred at the expense of making your interface more complex. So the ideal is to minimize both the amounts of information that needs to be transferred, as well as the number of points where it can be transferred. So in summary, if you have flexible code, your concerns are separated. Now, if you have separated concerns, you can view your code with much more modularity than you would have before. And coupling is the result of needing to communicate between modules. You should be able to reduce coupling as much as possible. So we know that a modular program is one that features strong separation of concerns. Now we're going to see why this way of thinking is so important to producing maintainable cross-platform apps. So if you have a project that needs to maintain clients on multiple platforms, you then need to figure out how to make the same logic for each platform. Now the trade-off is always going to be between being completely cross-platform, which means that you don't have an app that fits in well with the rest of the apps on your system, or writing the entire app for each platform, which is going to double your code base, means you have to test everything twice. You're going to spend twice as much developer time. So the alternative is to make it so that as much of the same code can be run on multiple platforms. So let's look at how you would do this. The first step is to choose a language that facilitates deploying code onto multiple sorts of devices. Now we're all Android developers here, which means that we're pretty comfortable with coding with Java. But the problem is that if you have a huge Java code base with lots of rich functionality, this is not going to help you on iOS because iPhone developers are going to be writing all their stuff in Objective-C. So if you begin in the native language of any platform, you're going to end up with a code base that doesn't run on the other platform. So writing everything in Java, it's not an option. So to figure out what language might be appropriate, let's consider what features we have in both languages. Now both are object-oriented. Now I say here garbage collected, that's not strictly speaking true for Objective-C, but it has automatic memory management that's close enough to garbage collection that it doesn't really matter for our purposes. And both have effectively static linking, so the names of methods within your classes and the names of your classes have to be fixed at compile time. So for Azdec docs, which is the application that I work on, we chose C++ as our code base, so that's what we're going to be talking about today. I personally don't really like C++ that much as a language, but as a language for a common code base, it actually makes a lot of sense. It has most of the features that I've just described. C++ mostly has manual memory management, so out of the box it's not quite as usable as a common language, especially for Java, because if you're putting Java objects on top of C++ code, you expect garbage collection to work. So in our case we use Boost Smart Pointers. These give us automatic memory management and the semantics are close enough to garbage collection in Java that it's close enough that you don't really care. So let's talk about using C++ on mobile platforms. If we're going to make an app with logic written in C++, then what we end up with is basically on the right, you have an Android app that uses a standard Android UI toolkit and you write your UI code in Java. And then you have your common logic code written in C++. Then if you want to make an iOS application, this looks pretty similar, except instead of writing your UI code in Java, you write your UI code in Objective-C using the iOS framework. Now getting C++ into Objective-C, this is surprisingly easy. Objective-C is just a thin wrapper on top of C and you can actually embed Objective-C calls in basically any language. So what about C++? Well, that's pretty easy. There's a language called Objective-C++. You just embed your Objective-C calls inside C++ code. The code compiles as you expect it. So this makes it really easy to take advantage of C++ from within Objective-C. Perhaps too easy. It basically just works. Now the situation in Android is considerably more complicated. If you want to make this process easy to manage, you have to spend a bit more time thinking about how to make things work. So let's take a look at why. Android works in a managed environment. It's kind of sorta looks like a Java VM. You write your code in Java. You execute it on this magic, not quite a JVM thing called Dalvik. Now despite not being a Java virtual machine in its entirety, it still provides a lot of features of Java. You get this thing called the Java-native interface. And when you combine that with the native development toolkit for Android, it lets you take advantage of code that is compiled down to machine code from within the safe managed constraints of Java. So basically it works like this. You declare a method as native within your Java code. The JNI figures out what function you need to call within your C library. And then your code magically gets executed. Easy. Now the problem, it's not actually that easy. The problem is that the JNI is actually quite complicated to write. This is a simple function that just takes a string from Java and then sends it back to you from C. C++ in this case. And for just for a simple function like this, there's already three complicated things that you have to do. Firstly, you have to get this method name up the top. Absolutely right. So this has the name of a class that your stub in Java is going to be in. It has the class name. It has the method name. This stops you from refactoring easily because if you change the class name, you change the method name. You have to find the C++ method and change its name as well. Getting variables out of Java land is also really difficult. It's got a complicated API with lots of words. And you have to manually manage your memory from within C or C++. So if you have any degree of complexity at all within your native code base, it's going to be impossible to get this right and maintain it. Once again, refactoring is really difficult and that's something you'd like to do within Java. So instead it makes much more sense to automatically generate code to bridge the gap. If you write your native cross-platform code in C++, then you get a tool called Java CPP. And this generates C++ code that matches the Java native interface for you. So you can make Java classes match up with your C++ interface. So Java CPP lets you construct wrappers. Sorry, wrappers. Yeah, wrappers are classes that you implement in Java. These contain instructions for Java CPP to generate your JNI code for you. Basically, you write one Java wrapper class for every C++ class that exposes an interface that you need to call. So to give you an idea of how simple this is, this is a C++ header class stub with a really bad set of indentation. So here's your public interface methods in C++ and here is the Java CPP implementation of that. All you need to do is declare each method that you want to generate code for just by saying this is a native method. You need to tell Java CPP what the name of the C++ class is and you need to tell Java CPP what C++ headers to include. These are all done by Java annotations. So basically all the configuration is actually done within your source code. You needn't even worry about there actually being C++ code there. It's really cool. This spits out a C++ source file that you can compile with the NDK. If you're using boost smart pointers, which we do because it makes our memory management easier, all you need to do is add this extra information. You say that this is wrapping a boost shared pointer instead of just a straight class and you need to say how to actually access the method on the C++ site. Once again, everything done with Java annotations. It's really good. So what you end up with is something that looks like this. It's a bunch of Java classes, a bunch of C++ classes and an interface between them. Now it should be clear to you that the interface here is the point where you do the wrapping between C++ and Java. So that means that whenever you change some C++ code that touches the interface, you have to update the matching Java code. So if Java needs to get some data out of C++ land to display things, then you're going to need to wrap a new class or method. So this increases your maintenance burden at the interface. So what I'm saying here is that every point where you need to relate between C++ and Java code, you introduce an unavoidable point of coupling. The more classes and methods that you need to wrap, the more broadly coupled the two aspects of your code, the portable core, the native UI, the more coupled they become. So if you don't think about structuring your interface correctly at the start, then you're going to have a difficult to maintain tightly coupled mess. So in summary, UI versus logic, all depends on the separation of concerns. And if you want to make your Android code talk to C++, you need to have wrappers, and wrappers introduces coupling. So we now know that if you decide to split your logic and your UI into a portable section and a native section, it's easy to end up with a difficult to write mess that's tightly coupled and is in two languages, which makes it even harder to maintain. So to finish up this talk, let's look at some design patterns that can help you think about how to separate your code into native and portable sections. So to remind you, we do this, we have design patterns to make it obvious how to separate your concerns. And what we're caring about separating is separating UI and logic. So the first one, you've probably heard of this one, it's MVC, Model View Controller. If you do iOS development, this is basically the pattern that iOS does encourages you to do to natively structure your app. So basically this involves separating each of your code into a model, which deals exclusively with the storage of data. The view, which deals exclusively with the display of data and taking inputs from your user. And the controller, which intermediates between the two. So in reality, the code is actually meant up more like this. Model connects to the controller, connects to the view. So if you're trying to separate between portable code and native UI code, then the interface between the two should probably sit between the controller and the view. The problem with MVC though is that it doesn't define a way to link up your view and your controller. So this means that the coupling between the view and the controller can be very strong if you don't plan things well in advance. If you need to write a wrapper between the controller and the view or you haven't planned on how you're going to link things up, it's going to be difficult unless you've actually planned to wrap things. So this problem is solved by a newer approach called MVVM, Model View Model. The point of MVVM is to make sure that there's a standard interface between the low level code and the display code. So as with MVC, we describe the components of MVVM in the wrong order. It actually looks something more like this. You have the model, which connects to the view model, which connects to the view. The basic idea is that you have a model and the model may actually also include the controller and a view. And the difference is that the view code and the low level model code is joined by a new class called the view model. Now the role of the view model is to give the view the set of information it needs to display stuff. And the view can set properties on the model to update the underlying code. So this means the interface between cross-platform and native code becomes between the view and the view model. But the difference is it's really obvious which bit of native code to wrap. You wrap the view model. It contains everything that the UI layer needs to be able to update things in the underlying code and to receive information from the underlying code. If you've used Django before, the Python web framework, you may be familiar with something like this. You have a model and a Django view, which is basically a controller, and you export data to the web through a view model that is used to render a template. Another pattern that we've adopted at ASDEC docs is to use a published subscribe event passing model. So the way that published subscribe works is that in our case we have an aggregator. Bits of UI tell the aggregator that it has an interest in certain types of events. So when an event occurs somewhere in the app, we publish that event to our aggregator, and that tells all the UI events that are all the UI aspects about the event. Now in practice, the events get raised on the portable side, and events get listened to on the UI side, which means the aggregator itself becomes the interface between the portable code and the native code. And this means the only things that need to be wrapped is the aggregator itself, as well as the different types of events you pass across the interface. This approach reduces a lot of coupling between the UI and the portable logic. So this is the point where I actually talk about the stuff I do in my day job. So I work on a file synchronization and management tool for business users to set docs. Now pretty early in the product's life, the decision was made to structure our code so that we had a portable core and a native UI. This is because we do a lot of things relating to correctness and security. Bugs can be shared across multiple platforms, so if we see a bug in one platform, we know that we can fix it in the other. We can make the same security guarantees about every platform that we target. And we're also a very small team of only, well, seven developers now. If we couldn't target multiple platforms, so we couldn't target multiple platforms if we didn't have substantial reuse of our code. Now, we pride ourselves on making an app that actually looks good and works well on both major platforms. We have a tool that looks at home on iOS, which is where it was originally designed. But we also have a version that looks great on Android. For that, we've needed our UI to be native and idiomatic on both platforms. So we have clients that are actually out there in the wild released on both iOS and Android. We actually have two iOS versions. We have an iPhone version and an iPad version, as well as the Android version. This approach separating portable core, our portable logic, and our UI as native has worked surprisingly well for us. And that gives me an opportunity to explain some lessons that we've learned. What we've learned, where things can improve. The first thing is that you should design to be portable from the outset. We made the active decision to make our apps work on multiple platforms. This means that we made active decisions about what code belongs on a single device and what code belongs on all devices. Now, sometimes we get these ideas wrong. These design decisions were incorrect. When we discover that we've made the wrong choice, that is we've put too much logic on the platform-specific side of the code, when the next developer goes and writes that functionality, instead of re-implementing it specifically for that platform, we take it down to the portable level so that if we come and have another client later on, the third person developing doesn't have to completely re-engineer everything again. Re-engineering functionality, a whole heap of times, this doesn't scale. You need to plan for things to work in multiple languages. C++ is a really complicated language as we've discovered. If you do things that depend on C++'s language constructs, its semantics, then that's not going to translate very well down to Java. Java doesn't have standalone functions. It doesn't have function pointers. It doesn't have copy construction in the same way that C++ does. If you want to write code that wraps C++ and the C++ code uses weird features that don't have an analog in Java, you're going to have a difficult time. So make sure that you only use constructs that have analogs in every language that you're going to be writing your UI code in. Plan for wrapping, figuring out how to wrap a C++ class effectively is a really large sync of developer time. It turns out that designing for iOS in the first place was a really bad idea for us because there's no real effort to call C++ stuff from within iOS because you have Objective C++. It's all the same language. So you need to think about how you're going to separate your code base in that case. Starting on Android first, really good idea because it's so difficult to figure out where the interface is. That means you actually plan more when you're doing the stuff for Android. So thinking about how C++ classes will look in another language is a great way to figure out what features of your common language to drop. So things like operator overloading don't work for us. Copy construction also difficult. C++ is a surprisingly unopinionated language as well. It will allow you to do basically anything you want within reason as long as the language... There's a feature in the language that lets you do it and there probably is. So decide what features of the language you want to use. Figure out what your design goals are for your project and then choose a subset of that language that will let you achieve these design goals because you're going to have multiple languages calling your cross-platform code. Also, make it really clear what code provides logic and figure out how a UI can attach itself to that logic. The most important separation of concerns you have when you're separating your portable logic from your native UI is between UI and logic. So choose design patterns for your interface that make this separation really, really clear. Model, view, view, model works really, really well for us in this case because it gives you a really obvious target point for what you're going to wrap. So in summary, structure your code to avoid coupling. Where your UI needs to get stuff out of your logic layer determines where the coupling is going to happen. Reduce the amount of coupling that you have and it's going to make it easier to write the UI. So aim for simplicity in the cross-platform interface. So in conclusion, that basically brings us to the end of the talk. We now know that you can write apps for each platform with a native, consistent UI for each platform, but with a substantial common code base. So how do we get there? Well, we started off by looking at the separation of concerns, which is basically the key idea in this entire talk. It's the basis of making modular, manageable software. And this is true because separating concerns gives us modularity. It gives us a chance to manage the complexity of a code base and the interfaces within it. And it results in easier interfaces to understand and to write code for. It also gives us portability. By separating concerns, it can make part of our code run on one specific platform but keep the rest of our code deliberately cross-platform. And that is the end of this talk. I have office hours at SpeakerConnect 3 p.m. today and 2.15 p.m. tomorrow. I've also got a talk on tomorrow on writing web services, which I strongly encourage you to come along to. So that's the end. Are there any questions? So can we get a mic over here and then there? So, yeah, over there first. Hello. Hi there. This is Pankaj here. So you talked about how to use common code which would be built in C++ on platforms like iOS and Android. But what about other platforms like, let's say I want to use the common code based on Blackberry and Windows as well? So, yeah, I mean, what do you think? I mean, so the answer is we were targeting originally can use C++ using the G++ compiler. Our iOS code base now compiles on Clang. So we made sure that our code works on multiple compilers because when you're writing code for Windows you only really have one option and that's the Microsoft compiler. And I believe we're working towards getting Windows working and our portable stuff worked as well on Windows as well. File system differences are like behavior file systems was our biggest hurdle, I think. But, you know, the approach works. It works on every platform we've extended it to so far. So the next question is there. Any idea how the C++ approach compares with using Csharp as in Xamarin? So we haven't tried that one because basically we only have a C++ code base. I'm not completely sure. I haven't looked at how the Csharp stuff works from the point of actually connecting the native Android UI toolkit into Csharp. I haven't seen if there are any bindings for that. But I believe that would be the biggest hurdle that you have. But that said, it's zapping, did you say? Zapping. Okay. So I believe that provides its own UI toolkit as well. So if you're using Csharp, then use the Csharp toolkits. That's not the approach that we talk. We wanted to use the native UI toolkits for every single platform. Hey, anyone else? Okay, one there and then there and then there. Hi, my name is Santosh. Hi. How does this approach vary from hybrid applications which is commonly out there, like HTML5 and stuff like that. So the development cycle and the way it is modular. So what do you mean by hybrid applications? I mean developing using HTML5 CSS and JavaScript and using something like PhoneGap or Titanium tool. So my view on things like PhoneGap, Titanium is that you can produce an okay app on multiple platforms but because the UI toolkit is sort of targeting the common subset of both platforms. You can't make something that's really idiomatic on each platform that you target. So if you want to make something that's really well behaved on every platform you've got to produce a native UI for each of them and I don't think PhoneGap or Titanium either of them produce something that would have worked in our case. You mean it's not more native? Sorry? It's not more native, is it? Something which using PhoneGap is not more native than what we do here. Is that what? Well yeah, PhoneGap, Titanium don't really produce something that's native enough. Okay, thank you. So I think there's one more over there. Hi, I'm Srikanth. So one interesting question I have is that why not JavaScript as a common language that powers this common UI logic and all this stuff? So I think I can say C++. I love C++. But what I felt is that this modern operating system, the mobile operating systems basically are making JavaScript as a first-class citizen. Once again I don't think JavaScript would have worked in our case. Just because we have we needed performance in searching and crypto and stuff like that for us, but it's something that can be done I've heard of other people using the JavaScript engine that's built into the platform as a way of doing the common code base. So you can do that in our case we didn't. But the concerns are still the same. Okay. One more? I'm trying to do something similar to what we have accomplished but then what I'm targeting is Windows, Linux and Android. But then the problem that I'm facing is basically that the threading part is just too complex to be managed from single library. Say we are developing using C++ but the problem is say if you just target using Linux you can use pre-threads but then the threading is different for Android. You don't have that concept exactly the same concept that you have in Linux as well as it's a different ball game. Okay. Or else the thing is if you use threading on the Java side then you'll have to make sure that you don't get those ANRs and all that. So you're talking about making sure that things behave responsibly on the UI side as well? As well as on the logic side because threading and network requests Right, so in our case what we actually discovered was a good approach was to do the threading and related things actually on the Java side and provide a C++ interface back into that. Judiciously choosing what bits of the Android toolkit and likewise the iOS toolkit to make use of and providing interfaces from C++ back into the native options worked quite well for us as well. All the threading is managed on the Java side That's it. So threading is managed on the Java side. One more question is have you used the Java native access? Sorry? Java native access? No. Cool, so I... Oh, one more? Okay. Let's go for this one, make it the last one and then we can have lunch. So you don't like using a C++ is a good idea to complicate a language to learn in the first place then it becomes difficult when you introduce templates and other things and in order to become a good C++ program itself takes a lot of time and developing an application in C++ also means the development releases time will also get increased. How do you justify the cost in that? Yeah, so C++ was I agree, it's a really complicated language. You can pick subsets of it though that make it easier to code. Pick something that translates well with Java and you end up with a C++ that's manageable so you don't do weird things with constructed behavior stuff like that. Using smart pointers gives you better memory management semantics than you would otherwise get. Basically, if you code free for all in C++ you're not going to be able to wrap it in Java because there are features in Java also C++ that don't translate down to Java but using the set of C++ stuff that you have actually makes it a lot easier. The other thing is that if you're going to go for native compile code you don't actually get that many choices. You get C++ and if you use a weird forked NDK you might get Objective-C as well. You've got to pick what the NDK provides if you want compiled code and you can either go for not object-oriented at all with C so super complicated with C++ you take your pick. C++ works well for us. You just have to be disciplined in picking the subset of features that you use. With that, I think I'm not going to keep you from lunch anymore so thank you all for listening and I hope you enjoyed the talk. Come see me at Speedy Connect 3 o'clock today if you have any more questions. Thank you.