This is part 1 of a 2 part series: part 2
In this part, I will show you a cool feature of Xamarin.Android that you probably don’t know about: the ability to embed .java files directly in your C# project and then execute that Java code.
Have you ever Google’d for how to do something in Android and found some Java code?
What are the options for using that Java code in your Xamarin app?
If it’s a large library, like an SDK, then you’ll want to get the .jar and create an Android Binding Library. That’s the topic of Part 2 in this series and we won’t talk about that further today.
If it’s a small bit of code, then your options are: 1. Convert the Java code to C# manually, 2. Include the Java code in your app and call it (the topic of this post)
I first learned about this feature by stumbling across a Xamarin sample.
If you’re not familiar with the Xamarin samples library, I recommend that you have a look through http://developer.xamarin.com/samples.
Xamarin have a comprehensive library of samples for all areas of the platform. They’re really good at keeping them up to date as new versions of Xamarin are released.
It’s a great way to discover features that might come in handy one day.
Let’s create a new Xamarin.Android project. I’ll be using latest version of Xamarin Studio on a Mac.
After creating the project, add a new .java file to the root of the Android project.
Here’s a simple .java class that we can use: download
Your project should look like this:
Next, we need to tell Xamarin Studio to treat that file as an Java source file and so that it will be compiled it into the application:
Right-click on the .java file, select Build Action > Android Java Source.
Finally, let’s instantiate an instance of that class, just to make sure it actually is in the app.
Add this to the onCreate code of your MainActivity, just before the button.Click assignment:
Let’s set a breakpoint on the
button.Click assignment and inspect the value of counter:
You can see that we’ve instantiated the class and have an instance - cool!
ClickCounter.Clicked() in the
It doesn’t compile! Why?
The problem is that the C# code doesn’t know what methods are on the class. It only knows it as a
We could cast the object so that the compiler knows what methods are on the object… but what would we cast it as?
The answer is that we need to create a Managed Callable Wrapper for the Java class. This is a C# declaration that tells Xamarin.Android how to marshal calls to the java class.
Here’s Xamarin documentation that explains managed callable wrapper in more detail.
If you’re like me you read that documentation and went “WTH?”.
Writing a MCW by hand can be quite difficult. In part 2 of this series where we use .jar libraries, I’ll show you how to generate the wrappers automagically.
For this exercise, I’ve generated an MCW for you: download
Let’s modify our code a bit:
It compiles! Congratulations, you’ve just learned how Xamarin.Android works.
MainActivity class you have in your app? That derives from
Activity, which is a MCW for the Android java
Button instance that we added the click event to? That is a MCW for the Android java
Don’t believe me? In your
MainActivity class, find this line of code:
Button button = FindViewById<Button> (Resource.Id.myButton);
Button and select Go to Declaration.
You’ll be shown the decompiled code for C#
Button. There’s not much there, is there. That’s because all the code does is define an MCW over the java
Almost all of the Xamarin.Android classes are MCW’s for their Android equivalents.
If you run the app and click the button, you will see that the button text changes on each click. The code that counts the clicks is encapsulated in the Java class we embedded into the application.
Generating an MCW by hand is not easy or fun. Realistically, it would have been easier to just convert this code to pure C#.
However, there are times when converting code to C# isn’t feasible. If the library is large, converting it to C# would be time-consuming and error prone. For that, you’ll want to generate MCW’s for the Java classes.
Fortunately Xamarin.Android comes with a utility to generate these MCW’s from .jar files. That will be subject for Part 2 of this post.
Full code for this project can be found on Github