Clean platform channel between Flutter and Android Java Native Code

Flutter works very well creating beautiful screens and animations, making API calls or storing key-value pairs. But sometimes you need to access more specific platforms API’s and so flutter provides the platform channels API. Here is a very good article explaining how it works at basic level.

And here is the official documentation.

The problem with default solution

In a nutshell, the platform channel works like a messaging system. You call it from flutter passing the name of method as a string and the arguments objects and on native side you need to router the method name received string to the correspondent native method, and after the result is computed send it back to flutter side.

But the problem is if your project needs to have a lot of native methods calls you will end up with a code like this:

Now imagine if your app have dozens of native calls, on some you need to have complex objects serialization and deserialization(as flutter channels does not support complex objects you need to pass then as strings), and you need to handle the exceptions to. After all you will end up with a dirt and error prone code.

Even if you don’t bother with having lot of if’s to manage maybe you will struggle with threads. By default the MethodCallHandler will execute on UI Thread and if you have slow computations or communications it will block the UI Thread. But then just execute the code inside MethodCallHandler in a new thread and it will works like a charm, right?! Nope, after the computation you will need to bring the result back to UI Thread as the result.success(), result.error() and result.notImplemented() need to execute on UI Thread.

The proposed solution

And if you cold have different classes (single-responsibility principle) each one with native methods that handle your calls, threat exceptions and receive and return complex objects (automatic serialization and deserialization), the code would have better readability and it will be less error prone, right? Yes, because of that I have designed a library that encapsulate the native calls logic and make it more clean and easy to use.

The logic is simple: annotate methods that can handle native calls, an helper class will get those methods dynamically using some reflection API and router the native calls to respective methods, parsing the arguments and the response automatically.

Here is one example of a class that can handle native calls, each method annotated with @NativeMethod can handle calls from flutter.

After creating the classes all you need is to register then and configure the flutter MethodCallHandler to redirect the calls to the helper class.

And it’s all done. You now can call the methods from flutter.

The library is still on development and code always can be better, so feel free to contribute if you liked it.

If you read this article so far I want thank you, this is my first article. In advance I want to apologize for any misunderstood, I’m not a native English speaker.

Thanks, best regards!

Mechatronics Engineer specialist on Software Engineering